From 35fdf992c00024aec85d7225784181b141624179 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Mon, 29 Apr 2024 17:13:55 +0000 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20change?= =?UTF-8?q?s=20introduced=20through=20rebase?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5 [skip ci] --- .ci/generate-buildkite-pipeline-premerge | 2 +- .ci/monolithic-linux.sh | 1 - .github/CODEOWNERS | 4 + .github/new-prs-labeler.yml | 4 + .github/workflows/libcxx-build-and-test.yaml | 9 - bolt/include/bolt/Passes/BinaryPasses.h | 3 +- bolt/include/bolt/Rewrite/RewriteInstance.h | 4 + bolt/lib/Profile/DataAggregator.cpp | 2 + bolt/lib/Rewrite/BinaryPassManager.cpp | 2 +- bolt/lib/Rewrite/BoltDiff.cpp | 2 +- bolt/lib/Rewrite/RewriteInstance.cpp | 156 +- ...d-sym-no-entry.c => fake-label-no-entry.c} | 6 +- bolt/test/X86/cdsplit-symbol-names.s | 1 + bolt/test/X86/indirect-goto-pie.test | 16 + bolt/test/X86/pre-aggregated-perf.test | 9 +- .../X86/shrinkwrapping-do-not-pessimize.s | 2 +- bolt/test/runtime/X86/Inputs/indirect_goto.c | 18 - bolt/test/runtime/X86/indirect-goto-pie.test | 10 - .../clang-tidy/ClangTidyCheck.cpp | 6 + clang-tools-extra/clang-tidy/ClangTidyCheck.h | 9 +- .../bugprone/BugproneTidyModule.cpp | 3 + .../clang-tidy/bugprone/CMakeLists.txt | 1 + .../EasilySwappableParametersCheck.cpp | 17 +- .../ReturnConstRefFromParameterCheck.cpp | 34 + .../ReturnConstRefFromParameterCheck.h | 40 + .../clang-tidy/modernize/CMakeLists.txt | 1 + .../MinMaxUseInitializerListCheck.cpp | 271 ++ .../modernize/MinMaxUseInitializerListCheck.h | 56 + .../modernize/ModernizeTidyModule.cpp | 3 + .../clang-tidy/modernize/UseNullptrCheck.h | 2 +- .../modernize/UseStartsEndsWithCheck.cpp | 103 +- .../modernize/UseStartsEndsWithCheck.h | 7 +- .../AvoidReturnWithVoidValueCheck.cpp | 7 +- .../clang-tidy/readability/CMakeLists.txt | 1 + .../MathMissingParenthesesCheck.cpp | 97 + .../readability/MathMissingParenthesesCheck.h | 34 + .../readability/ReadabilityTidyModule.cpp | 3 + .../clangd/CodeCompletionStrings.cpp | 2 +- clang-tools-extra/docs/ReleaseNotes.rst | 47 +- .../return-const-ref-from-parameter.rst | 31 + .../docs/clang-tidy/checks/cert/env33-c.rst | 2 +- .../docs/clang-tidy/checks/list.rst | 3 + .../min-max-use-initializer-list.rst | 50 + .../checks/modernize/use-nullptr.rst | 2 +- .../checks/modernize/use-starts-ends-with.rst | 8 +- .../readability/math-missing-parentheses.rst | 27 + .../clang-tidy/checkers/Inputs/Headers/string | 4 + .../checkers/Inputs/Headers/string.h | 1 + .../abseil/redundant-strcat-calls.cpp | 2 - .../return-const-ref-from-parameter.cpp | 31 + .../min-max-use-initializer-list.cpp | 305 ++ .../checkers/modernize/use-nullptr-c23.c | 139 + .../checkers/modernize/use-nullptr.c | 2 +- .../modernize/use-starts-ends-with.cpp | 55 + .../readability/math-missing-parentheses.cpp | 120 + .../Inputs/config-files/5/.clang-tidy | 4 + .../infrastructure/config-files.cpp | 8 + .../test/pp-trace/pp-trace-pragma-general.cpp | 6 + .../test/pp-trace/pp-trace-pragma-ms.cpp | 8 +- .../test/pp-trace/pp-trace-pragma-opencl.cpp | 6 + clang/CMakeLists.txt | 4 + clang/cmake/caches/Release.cmake | 135 +- clang/cmake/caches/VectorEngine.cmake | 2 + clang/docs/LanguageExtensions.rst | 33 +- clang/docs/LibTooling.rst | 22 +- clang/docs/OpenMPSupport.rst | 4 +- clang/docs/ReleaseNotes.rst | 47 + clang/docs/UsersManual.rst | 89 +- clang/include/clang-c/Index.h | 3 +- clang/include/clang/APINotes/Types.h | 22 +- clang/include/clang/AST/ASTContext.h | 17 +- clang/include/clang/AST/ASTNodeTraverser.h | 6 + clang/include/clang/AST/AbstractBasicReader.h | 4 +- clang/include/clang/AST/AbstractBasicWriter.h | 4 +- clang/include/clang/AST/BuiltinTypes.def | 2 +- clang/include/clang/AST/ComputeDependence.h | 4 +- clang/include/clang/AST/Decl.h | 46 +- clang/include/clang/AST/DeclBase.h | 11 +- clang/include/clang/AST/DeclCXX.h | 59 +- .../include/clang/AST/DeclContextInternals.h | 39 +- clang/include/clang/AST/DeclFriend.h | 2 +- clang/include/clang/AST/DeclID.h | 227 ++ clang/include/clang/AST/DeclObjC.h | 30 +- clang/include/clang/AST/DeclOpenMP.h | 17 +- clang/include/clang/AST/DeclTemplate.h | 50 +- clang/include/clang/AST/Expr.h | 269 ++ clang/include/clang/AST/ExprOpenMP.h | 124 - clang/include/clang/AST/ExternalASTSource.h | 6 +- clang/include/clang/AST/RecursiveASTVisitor.h | 2 +- clang/include/clang/AST/Type.h | 262 +- .../FlowSensitive/DataflowEnvironment.h | 15 + .../clang/Analysis/FlowSensitive/Transfer.h | 3 +- clang/include/clang/Basic/Attr.td | 12 +- .../include/clang/Basic/AttributeCommonInfo.h | 6 +- .../clang/Basic/DiagnosticFrontendKinds.td | 3 + .../clang/Basic/DiagnosticParseKinds.td | 9 + .../clang/Basic/DiagnosticSemaKinds.td | 21 +- clang/include/clang/Basic/FileManager.h | 10 + clang/include/clang/Basic/LangOptions.h | 18 + .../include/clang/Basic/PointerAuthOptions.h | 23 + clang/include/clang/Basic/StmtNodes.td | 2 +- clang/include/clang/Basic/TargetInfo.h | 10 + clang/include/clang/Basic/arm_neon.td | 2 +- clang/include/clang/Basic/arm_sve.td | 27 +- clang/include/clang/Basic/riscv_vector.td | 97 +- clang/include/clang/CIR/CMakeLists.txt | 6 + .../include/clang/CIR/Dialect/CMakeLists.txt | 1 + .../include/clang/CIR/Dialect/IR/CIRDialect.h | 16 + .../clang/CIR/Dialect/IR/CIRDialect.td | 44 + clang/include/clang/CIR/Dialect/IR/CIROps.td | 19 + .../clang/CIR/Dialect/IR/CMakeLists.txt | 16 + clang/include/clang/Driver/Options.td | 21 +- clang/include/clang/ExtractAPI/API.h | 135 +- clang/include/clang/ExtractAPI/APIRecords.inc | 16 +- .../clang/ExtractAPI/DeclarationFragments.h | 84 +- .../clang/ExtractAPI/ExtractAPIVisitor.h | 76 +- clang/include/clang/Frontend/ASTUnit.h | 2 +- .../clang/Frontend/MultiplexConsumer.h | 2 +- clang/include/clang/Lex/HeaderSearch.h | 14 +- clang/include/clang/Parse/Parser.h | 44 +- clang/include/clang/Sema/DeclSpec.h | 10 +- .../clang/Sema/MultiplexExternalSemaSource.h | 2 +- clang/include/clang/Sema/ParsedAttr.h | 1 + clang/include/clang/Sema/Sema.h | 1 + clang/include/clang/Sema/SemaOpenACC.h | 6 + .../include/clang/Serialization/ASTBitCodes.h | 121 +- .../ASTDeserializationListener.h | 2 +- clang/include/clang/Serialization/ASTReader.h | 138 +- .../clang/Serialization/ASTRecordReader.h | 14 +- clang/include/clang/Serialization/ASTWriter.h | 28 +- .../include/clang/Serialization/ModuleFile.h | 4 +- .../StaticAnalyzer/Core/PathSensitive/Store.h | 14 +- .../clang/Support/RISCVVIntrinsicUtils.h | 3 +- clang/lib/APINotes/APINotesFormat.h | 5 +- clang/lib/APINotes/APINotesReader.cpp | 7 + clang/lib/APINotes/APINotesWriter.cpp | 7 +- clang/lib/APINotes/APINotesYAMLCompiler.cpp | 5 + clang/lib/AST/ASTContext.cpp | 15 +- clang/lib/AST/ComputeDependence.cpp | 7 +- clang/lib/AST/Decl.cpp | 49 +- clang/lib/AST/DeclBase.cpp | 8 +- clang/lib/AST/DeclCXX.cpp | 74 +- clang/lib/AST/DeclFriend.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 29 +- clang/lib/AST/DeclOpenMP.cpp | 14 +- clang/lib/AST/DeclTemplate.cpp | 47 +- clang/lib/AST/Expr.cpp | 6 +- clang/lib/AST/ExprClassification.cpp | 2 +- clang/lib/AST/ExprConstant.cpp | 136 +- clang/lib/AST/ExternalASTSource.cpp | 4 +- clang/lib/AST/Interp/ByteCodeExprGen.cpp | 426 +- clang/lib/AST/Interp/ByteCodeExprGen.h | 8 +- clang/lib/AST/Interp/ByteCodeStmtGen.cpp | 24 +- clang/lib/AST/Interp/Context.cpp | 33 + clang/lib/AST/Interp/Context.h | 3 + clang/lib/AST/Interp/Descriptor.cpp | 74 +- clang/lib/AST/Interp/Descriptor.h | 3 + clang/lib/AST/Interp/Disasm.cpp | 31 +- clang/lib/AST/Interp/Interp.h | 12 +- clang/lib/AST/Interp/Opcodes.td | 2 +- clang/lib/AST/Interp/Program.cpp | 3 +- clang/lib/AST/ItaniumMangle.cpp | 2 +- clang/lib/AST/NSAPI.cpp | 2 +- clang/lib/AST/StmtPrinter.cpp | 4 +- clang/lib/AST/StmtProfile.cpp | 2 +- clang/lib/AST/Type.cpp | 18 +- clang/lib/AST/TypeLoc.cpp | 2 +- clang/lib/Analysis/FlowSensitive/ASTOps.cpp | 16 +- .../FlowSensitive/DataflowEnvironment.cpp | 71 +- clang/lib/Analysis/FlowSensitive/Transfer.cpp | 64 +- .../TypeErasedDataflowAnalysis.cpp | 4 +- clang/lib/Basic/FileManager.cpp | 14 +- clang/lib/Basic/Targets/ARM.h | 4 + clang/lib/Basic/Targets/AVR.h | 4 + clang/lib/Basic/Targets/BPF.h | 4 + clang/lib/Basic/Targets/M68k.h | 4 + clang/lib/Basic/Targets/Mips.h | 4 + clang/lib/Basic/Targets/PPC.h | 8 + clang/lib/Basic/Targets/RISCV.h | 6 +- clang/lib/Basic/Targets/Sparc.h | 4 + clang/lib/Basic/Targets/SystemZ.h | 4 + clang/lib/Basic/Targets/WebAssembly.cpp | 23 +- clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/CIR/CMakeLists.txt | 4 + clang/lib/CIR/Dialect/CMakeLists.txt | 1 + clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 13 + clang/lib/CIR/Dialect/IR/CMakeLists.txt | 3 + clang/lib/CodeGen/CGBuiltin.cpp | 41 +- clang/lib/CodeGen/CGCall.cpp | 18 +- clang/lib/CodeGen/CGCleanup.cpp | 76 +- clang/lib/CodeGen/CGCleanup.h | 57 +- clang/lib/CodeGen/CGCoroutine.cpp | 6 +- clang/lib/CodeGen/CGDebugInfo.cpp | 21 +- clang/lib/CodeGen/CGDecl.cpp | 87 +- clang/lib/CodeGen/CGExpr.cpp | 30 +- clang/lib/CodeGen/CGExprAgg.cpp | 87 +- clang/lib/CodeGen/CGExprCXX.cpp | 38 +- clang/lib/CodeGen/CGExprConstant.cpp | 108 +- clang/lib/CodeGen/CGExprScalar.cpp | 2 +- clang/lib/CodeGen/CGLoopInfo.cpp | 2 - clang/lib/CodeGen/CGObjCGNU.cpp | 34 +- clang/lib/CodeGen/CGOpenMPRuntime.cpp | 43 +- clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 4 +- clang/lib/CodeGen/CGStmtOpenMP.cpp | 4 +- clang/lib/CodeGen/CodeGenFunction.cpp | 6 + clang/lib/CodeGen/CodeGenFunction.h | 115 +- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenModule.h | 3 + clang/lib/CodeGen/CodeGenTypes.cpp | 2 +- clang/lib/Driver/Driver.cpp | 2 +- clang/lib/Driver/SanitizerArgs.cpp | 8 +- clang/lib/Driver/ToolChain.cpp | 15 +- clang/lib/Driver/ToolChains/AIX.cpp | 2 - clang/lib/Driver/ToolChains/AMDGPU.cpp | 3 +- clang/lib/Driver/ToolChains/Arch/RISCV.cpp | 2 +- clang/lib/Driver/ToolChains/Clang.cpp | 62 +- clang/lib/Driver/ToolChains/CommonArgs.cpp | 110 +- clang/lib/Driver/ToolChains/Flang.cpp | 11 +- clang/lib/Driver/ToolChains/Gnu.cpp | 6 +- clang/lib/Driver/ToolChains/Linux.cpp | 19 - clang/lib/Driver/ToolChains/Linux.h | 4 - clang/lib/ExtractAPI/API.cpp | 22 + clang/lib/ExtractAPI/DeclarationFragments.cpp | 17 +- .../Serialization/SymbolGraphSerializer.cpp | 36 +- clang/lib/Format/Format.cpp | 4 +- clang/lib/Format/FormatToken.h | 8 +- clang/lib/Format/TokenAnnotator.cpp | 39 +- clang/lib/Format/UnwrappedLineParser.cpp | 65 +- clang/lib/Format/WhitespaceManager.cpp | 42 +- clang/lib/Frontend/ASTUnit.cpp | 9 +- clang/lib/Frontend/CompilerInstance.cpp | 4 + clang/lib/Frontend/FrontendAction.cpp | 13 +- clang/lib/Frontend/InitPreprocessor.cpp | 15 +- clang/lib/Frontend/MultiplexConsumer.cpp | 4 +- clang/lib/Headers/cpuid.h | 6 +- clang/lib/Lex/HeaderSearch.cpp | 1 + clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 + clang/lib/Parse/ParseDecl.cpp | 47 +- clang/lib/Parse/ParseExpr.cpp | 26 +- clang/lib/Parse/ParseHLSL.cpp | 18 +- clang/lib/Parse/ParseObjc.cpp | 1 + clang/lib/Parse/ParseOpenACC.cpp | 4 +- clang/lib/Parse/ParseTemplate.cpp | 5 + clang/lib/Parse/Parser.cpp | 2 + clang/lib/Sema/DeclSpec.cpp | 4 +- clang/lib/Sema/JumpDiagnostics.cpp | 3 +- .../lib/Sema/MultiplexExternalSemaSource.cpp | 2 +- clang/lib/Sema/SemaAPINotes.cpp | 5 + clang/lib/Sema/SemaChecking.cpp | 58 +- clang/lib/Sema/SemaDecl.cpp | 54 +- clang/lib/Sema/SemaDeclCXX.cpp | 18 +- clang/lib/Sema/SemaDeclObjC.cpp | 4 + clang/lib/Sema/SemaExceptionSpec.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 24 +- clang/lib/Sema/SemaInit.cpp | 19 +- clang/lib/Sema/SemaOpenACC.cpp | 15 + clang/lib/Sema/SemaOpenMP.cpp | 71 +- clang/lib/Sema/SemaRISCVVectorLookup.cpp | 1 + clang/lib/Sema/SemaStmtAttr.cpp | 18 +- clang/lib/Sema/SemaTemplate.cpp | 2 + clang/lib/Sema/SemaTemplateDeduction.cpp | 3 + clang/lib/Sema/SemaTemplateInstantiate.cpp | 18 +- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 1 + clang/lib/Sema/TreeTransform.h | 53 +- clang/lib/Serialization/ASTCommon.cpp | 4 +- clang/lib/Serialization/ASTReader.cpp | 264 +- clang/lib/Serialization/ASTReaderDecl.cpp | 123 +- clang/lib/Serialization/ASTReaderInternals.h | 8 +- clang/lib/Serialization/ASTReaderStmt.cpp | 18 +- clang/lib/Serialization/ASTWriter.cpp | 170 +- clang/lib/Serialization/ASTWriterDecl.cpp | 22 +- clang/lib/Serialization/ASTWriterStmt.cpp | 13 +- .../Checkers/DereferenceChecker.cpp | 4 +- .../Checkers/IdenticalExprChecker.cpp | 2 +- .../StaticAnalyzer/Checkers/StreamChecker.cpp | 2 +- clang/lib/StaticAnalyzer/Checkers/Taint.cpp | 14 +- .../Checkers/WebKit/PtrTypesSemantics.h | 3 + .../WebKit/UncountedCallArgsChecker.cpp | 7 + clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 2 +- .../DependencyScanningWorker.cpp | 3 + .../Inputs/Headers/SwiftImportAs.apinotes | 4 + .../APINotes/Inputs/Headers/SwiftImportAs.h | 3 + clang/test/APINotes/swift-import-as.cpp | 10 + clang/test/AST/Interp/c.c | 7 + clang/test/AST/Interp/cxx23.cpp | 16 + clang/test/AST/Interp/functions.cpp | 16 + clang/test/AST/Interp/opencl.cl | 32 + clang/test/AST/Interp/records.cpp | 114 +- clang/test/AST/ast-dump-fpfeatures.cpp | 68 +- clang/test/AST/ast-dump-fpfeatures.m | 29 + clang/test/AST/ast-dump-late-parsing.cpp | 24 + clang/test/AST/ast-dump-macro-json.c | 4 +- clang/test/AST/ast-dump-pragma-unroll.cpp | 31 + clang/test/AST/ast-dump-recovery.cpp | 8 + ...dump-template-json-win32-mangler-crash.cpp | 88 + clang/test/AST/ast-dump-templates.cpp | 14 + ...ll-args-regression-traverse-decl-crash.cpp | 7 + .../Analysis/Checkers/WebKit/call-args.cpp | 2 +- .../Analysis/Checkers/WebKit/mock-types.h | 67 +- .../relevant_lines/multifile.c | 2 +- clang/test/CXX/drs/cwg2149.cpp | 77 + clang/test/CXX/drs/cwg650.cpp | 2 +- clang/test/CXX/drs/dr20xx.cpp | 2 +- clang/test/CXX/drs/dr21xx.cpp | 2 + clang/test/CXX/drs/dr24xx.cpp | 4 +- clang/test/CXX/drs/dr25xx.cpp | 4 +- clang/test/CXX/drs/dr28xx.cpp | 12 +- clang/test/CXX/expr/expr.const/p5-26.cpp | 7 + clang/test/CXX/stmt.stmt/stmt.return/p6.cpp | 25 + .../non-overloaded/bfloat16/vcreate.c | 477 +++ .../non-policy/non-overloaded/bfloat16/vget.c | 333 ++ .../non-overloaded/bfloat16/vle16.c | 132 + .../non-overloaded/bfloat16/vle16ff.c | 177 + .../non-overloaded/bfloat16/vlmul_ext_v.c | 159 + .../non-overloaded/bfloat16/vlmul_trunc_v.c | 159 + .../non-overloaded/bfloat16/vloxei16.c | 141 + .../non-overloaded/bfloat16/vloxseg2ei16.c | 121 + .../non-overloaded/bfloat16/vloxseg3ei16.c | 99 + .../non-overloaded/bfloat16/vloxseg4ei16.c | 99 + .../non-overloaded/bfloat16/vloxseg5ei16.c | 77 + .../non-overloaded/bfloat16/vloxseg6ei16.c | 77 + .../non-overloaded/bfloat16/vloxseg7ei16.c | 77 + .../non-overloaded/bfloat16/vloxseg8ei16.c | 77 + .../non-overloaded/bfloat16/vlse16.c | 141 + .../non-overloaded/bfloat16/vlseg2e16.c | 114 + .../non-overloaded/bfloat16/vlseg2e16ff.c | 179 + .../non-overloaded/bfloat16/vlseg3e16.c | 93 + .../non-overloaded/bfloat16/vlseg3e16ff.c | 161 + .../non-overloaded/bfloat16/vlseg4e16.c | 93 + .../non-overloaded/bfloat16/vlseg4e16ff.c | 177 + .../non-overloaded/bfloat16/vlseg5e16.c | 72 + .../non-overloaded/bfloat16/vlseg5e16ff.c | 147 + .../non-overloaded/bfloat16/vlseg6e16.c | 72 + .../non-overloaded/bfloat16/vlseg6e16ff.c | 159 + .../non-overloaded/bfloat16/vlseg7e16.c | 72 + .../non-overloaded/bfloat16/vlseg7e16ff.c | 171 + .../non-overloaded/bfloat16/vlseg8e16.c | 72 + .../non-overloaded/bfloat16/vlseg8e16ff.c | 183 + .../non-overloaded/bfloat16/vlsseg2e16.c | 119 + .../non-overloaded/bfloat16/vlsseg3e16.c | 97 + .../non-overloaded/bfloat16/vlsseg4e16.c | 97 + .../non-overloaded/bfloat16/vlsseg5e16.c | 75 + .../non-overloaded/bfloat16/vlsseg6e16.c | 75 + .../non-overloaded/bfloat16/vlsseg7e16.c | 75 + .../non-overloaded/bfloat16/vlsseg8e16.c | 75 + .../non-overloaded/bfloat16/vluxei16.c | 141 + .../non-overloaded/bfloat16/vluxseg2ei16.c | 121 + .../non-overloaded/bfloat16/vluxseg3ei16.c | 99 + .../non-overloaded/bfloat16/vluxseg4ei16.c | 99 + .../non-overloaded/bfloat16/vluxseg5ei16.c | 77 + .../non-overloaded/bfloat16/vluxseg6ei16.c | 77 + .../non-overloaded/bfloat16/vluxseg7ei16.c | 77 + .../non-overloaded/bfloat16/vluxseg8ei16.c | 77 + .../non-overloaded/bfloat16/vreinterpret.c | 249 ++ .../non-overloaded/bfloat16/vse16.c | 135 + .../non-policy/non-overloaded/bfloat16/vset.c | 364 ++ .../non-overloaded/bfloat16/vsoxei16.c | 141 + .../non-overloaded/bfloat16/vsoxseg2ei16.c | 141 + .../non-overloaded/bfloat16/vsoxseg3ei16.c | 123 + .../non-overloaded/bfloat16/vsoxseg4ei16.c | 131 + .../non-overloaded/bfloat16/vsoxseg5ei16.c | 107 + .../non-overloaded/bfloat16/vsoxseg6ei16.c | 113 + .../non-overloaded/bfloat16/vsoxseg7ei16.c | 119 + .../non-overloaded/bfloat16/vsoxseg8ei16.c | 125 + .../non-overloaded/bfloat16/vsse16.c | 141 + .../non-overloaded/bfloat16/vsseg2e16.c | 134 + .../non-overloaded/bfloat16/vsseg3e16.c | 117 + .../non-overloaded/bfloat16/vsseg4e16.c | 125 + .../non-overloaded/bfloat16/vsseg5e16.c | 102 + .../non-overloaded/bfloat16/vsseg6e16.c | 108 + .../non-overloaded/bfloat16/vsseg7e16.c | 114 + .../non-overloaded/bfloat16/vsseg8e16.c | 120 + .../non-overloaded/bfloat16/vssseg2e16.c | 139 + .../non-overloaded/bfloat16/vssseg3e16.c | 121 + .../non-overloaded/bfloat16/vssseg4e16.c | 129 + .../non-overloaded/bfloat16/vssseg5e16.c | 105 + .../non-overloaded/bfloat16/vssseg6e16.c | 111 + .../non-overloaded/bfloat16/vssseg7e16.c | 117 + .../non-overloaded/bfloat16/vssseg8e16.c | 123 + .../non-overloaded/bfloat16/vsuxei16.c | 141 + .../non-overloaded/bfloat16/vsuxseg2ei16.c | 141 + .../non-overloaded/bfloat16/vsuxseg3ei16.c | 123 + .../non-overloaded/bfloat16/vsuxseg4ei16.c | 131 + .../non-overloaded/bfloat16/vsuxseg5ei16.c | 107 + .../non-overloaded/bfloat16/vsuxseg6ei16.c | 113 + .../non-overloaded/bfloat16/vsuxseg7ei16.c | 119 + .../non-overloaded/bfloat16/vsuxseg8ei16.c | 125 + .../non-overloaded/bfloat16/vundefined.c | 280 ++ .../non-policy/non-overloaded/vaesdf.c | 10 - .../non-policy/non-overloaded/vaesdm.c | 10 - .../non-policy/non-overloaded/vaesef.c | 10 - .../non-policy/non-overloaded/vaesem.c | 10 - .../non-policy/non-overloaded/vaesz.c | 10 - .../non-policy/non-overloaded/vsm4r.c | 10 - .../non-policy/overloaded/bfloat16/vget.c | 333 ++ .../non-policy/overloaded/bfloat16/vle16.c | 72 + .../non-policy/overloaded/bfloat16/vle16ff.c | 93 + .../overloaded/bfloat16/vlmul_ext_v.c | 159 + .../overloaded/bfloat16/vlmul_trunc_v.c | 159 + .../non-policy/overloaded/bfloat16/vloxei16.c | 141 + .../overloaded/bfloat16/vloxseg2ei16.c | 121 + .../overloaded/bfloat16/vloxseg3ei16.c | 99 + .../overloaded/bfloat16/vloxseg4ei16.c | 99 + .../overloaded/bfloat16/vloxseg5ei16.c | 77 + .../overloaded/bfloat16/vloxseg6ei16.c | 77 + .../overloaded/bfloat16/vloxseg7ei16.c | 77 + .../overloaded/bfloat16/vloxseg8ei16.c | 77 + .../non-policy/overloaded/bfloat16/vlse16.c | 75 + .../overloaded/bfloat16/vlseg2e16.c | 64 + .../overloaded/bfloat16/vlseg2e16ff.c | 94 + .../overloaded/bfloat16/vlseg3e16.c | 53 + .../overloaded/bfloat16/vlseg3e16ff.c | 85 + .../overloaded/bfloat16/vlseg4e16.c | 53 + .../overloaded/bfloat16/vlseg4e16ff.c | 93 + .../overloaded/bfloat16/vlseg5e16.c | 42 + .../overloaded/bfloat16/vlseg5e16ff.c | 78 + .../overloaded/bfloat16/vlseg6e16.c | 42 + .../overloaded/bfloat16/vlseg6e16ff.c | 84 + .../overloaded/bfloat16/vlseg7e16.c | 42 + .../overloaded/bfloat16/vlseg7e16ff.c | 90 + .../overloaded/bfloat16/vlseg8e16.c | 42 + .../overloaded/bfloat16/vlseg8e16ff.c | 96 + .../overloaded/bfloat16/vlsseg2e16.c | 64 + .../overloaded/bfloat16/vlsseg3e16.c | 53 + .../overloaded/bfloat16/vlsseg4e16.c | 53 + .../overloaded/bfloat16/vlsseg5e16.c | 42 + .../overloaded/bfloat16/vlsseg6e16.c | 42 + .../overloaded/bfloat16/vlsseg7e16.c | 42 + .../overloaded/bfloat16/vlsseg8e16.c | 42 + .../non-policy/overloaded/bfloat16/vluxei16.c | 141 + .../overloaded/bfloat16/vluxseg2ei16.c | 121 + .../overloaded/bfloat16/vluxseg3ei16.c | 99 + .../overloaded/bfloat16/vluxseg4ei16.c | 99 + .../overloaded/bfloat16/vluxseg5ei16.c | 77 + .../overloaded/bfloat16/vluxseg6ei16.c | 77 + .../overloaded/bfloat16/vluxseg7ei16.c | 77 + .../overloaded/bfloat16/vluxseg8ei16.c | 77 + .../overloaded/bfloat16/vreinterpret.c | 249 ++ .../non-policy/overloaded/bfloat16/vse16.c | 135 + .../non-policy/overloaded/bfloat16/vset.c | 364 ++ .../non-policy/overloaded/bfloat16/vsoxei16.c | 141 + .../overloaded/bfloat16/vsoxseg2ei16.c | 141 + .../overloaded/bfloat16/vsoxseg3ei16.c | 123 + .../overloaded/bfloat16/vsoxseg4ei16.c | 131 + .../overloaded/bfloat16/vsoxseg5ei16.c | 107 + .../overloaded/bfloat16/vsoxseg6ei16.c | 113 + .../overloaded/bfloat16/vsoxseg7ei16.c | 119 + .../overloaded/bfloat16/vsoxseg8ei16.c | 125 + .../non-policy/overloaded/bfloat16/vsse16.c | 141 + .../overloaded/bfloat16/vsseg2e16.c | 134 + .../overloaded/bfloat16/vsseg3e16.c | 117 + .../overloaded/bfloat16/vsseg4e16.c | 125 + .../overloaded/bfloat16/vsseg5e16.c | 102 + .../overloaded/bfloat16/vsseg6e16.c | 108 + .../overloaded/bfloat16/vsseg7e16.c | 114 + .../overloaded/bfloat16/vsseg8e16.c | 120 + .../overloaded/bfloat16/vssseg2e16.c | 139 + .../overloaded/bfloat16/vssseg3e16.c | 121 + .../overloaded/bfloat16/vssseg4e16.c | 129 + .../overloaded/bfloat16/vssseg5e16.c | 105 + .../overloaded/bfloat16/vssseg6e16.c | 111 + .../overloaded/bfloat16/vssseg7e16.c | 117 + .../overloaded/bfloat16/vssseg8e16.c | 123 + .../non-policy/overloaded/bfloat16/vsuxei16.c | 141 + .../overloaded/bfloat16/vsuxseg2ei16.c | 141 + .../overloaded/bfloat16/vsuxseg3ei16.c | 123 + .../overloaded/bfloat16/vsuxseg4ei16.c | 131 + .../overloaded/bfloat16/vsuxseg5ei16.c | 107 + .../overloaded/bfloat16/vsuxseg6ei16.c | 113 + .../overloaded/bfloat16/vsuxseg7ei16.c | 119 + .../overloaded/bfloat16/vsuxseg8ei16.c | 125 + .../non-policy/overloaded/vaesdf.c | 10 - .../non-policy/overloaded/vaesdm.c | 10 - .../non-policy/overloaded/vaesef.c | 10 - .../non-policy/overloaded/vaesem.c | 10 - .../non-policy/overloaded/vaesz.c | 10 - .../non-policy/overloaded/vsm4r.c | 10 - .../policy/non-overloaded/bfloat16/vle16.c | 249 ++ .../policy/non-overloaded/bfloat16/vle16ff.c | 321 ++ .../policy/non-overloaded/bfloat16/vloxei16.c | 249 ++ .../non-overloaded/bfloat16/vloxseg2ei16.c | 249 ++ .../non-overloaded/bfloat16/vloxseg3ei16.c | 217 + .../non-overloaded/bfloat16/vloxseg4ei16.c | 233 ++ .../non-overloaded/bfloat16/vloxseg5ei16.c | 189 + .../non-overloaded/bfloat16/vloxseg6ei16.c | 201 + .../non-overloaded/bfloat16/vloxseg7ei16.c | 213 + .../non-overloaded/bfloat16/vloxseg8ei16.c | 225 + .../policy/non-overloaded/bfloat16/vlse16.c | 249 ++ .../non-overloaded/bfloat16/vlseg2e16.c | 249 ++ .../non-overloaded/bfloat16/vlseg2e16ff.c | 369 ++ .../non-overloaded/bfloat16/vlseg3e16.c | 217 + .../non-overloaded/bfloat16/vlseg3e16ff.c | 345 ++ .../non-overloaded/bfloat16/vlseg4e16.c | 233 ++ .../non-overloaded/bfloat16/vlseg4e16ff.c | 393 ++ .../non-overloaded/bfloat16/vlseg5e16.c | 189 + .../non-overloaded/bfloat16/vlseg5e16ff.c | 333 ++ .../non-overloaded/bfloat16/vlseg6e16.c | 201 + .../non-overloaded/bfloat16/vlseg6e16ff.c | 369 ++ .../non-overloaded/bfloat16/vlseg7e16.c | 213 + .../non-overloaded/bfloat16/vlseg7e16ff.c | 405 ++ .../non-overloaded/bfloat16/vlseg8e16.c | 225 + .../non-overloaded/bfloat16/vlseg8e16ff.c | 441 ++ .../non-overloaded/bfloat16/vlsseg2e16.c | 249 ++ .../non-overloaded/bfloat16/vlsseg3e16.c | 217 + .../non-overloaded/bfloat16/vlsseg4e16.c | 233 ++ .../non-overloaded/bfloat16/vlsseg5e16.c | 189 + .../non-overloaded/bfloat16/vlsseg6e16.c | 201 + .../non-overloaded/bfloat16/vlsseg7e16.c | 213 + .../non-overloaded/bfloat16/vlsseg8e16.c | 225 + .../policy/non-overloaded/bfloat16/vluxei16.c | 249 ++ .../non-overloaded/bfloat16/vluxseg2ei16.c | 249 ++ .../non-overloaded/bfloat16/vluxseg3ei16.c | 217 + .../non-overloaded/bfloat16/vluxseg4ei16.c | 233 ++ .../non-overloaded/bfloat16/vluxseg5ei16.c | 189 + .../non-overloaded/bfloat16/vluxseg6ei16.c | 201 + .../non-overloaded/bfloat16/vluxseg7ei16.c | 213 + .../non-overloaded/bfloat16/vluxseg8ei16.c | 225 + .../policy/non-overloaded/vaesdf.c | 10 - .../policy/non-overloaded/vaesdm.c | 10 - .../policy/non-overloaded/vaesef.c | 10 - .../policy/non-overloaded/vaesem.c | 10 - .../policy/non-overloaded/vaesz.c | 10 - .../policy/non-overloaded/vsm4r.c | 10 - .../policy/overloaded/bfloat16/vle16.c | 273 ++ .../policy/overloaded/bfloat16/vle16ff.c | 363 ++ .../policy/overloaded/bfloat16/vloxei16.c | 291 ++ .../policy/overloaded/bfloat16/vloxseg2ei16.c | 306 ++ .../policy/overloaded/bfloat16/vloxseg3ei16.c | 264 ++ .../policy/overloaded/bfloat16/vloxseg4ei16.c | 280 ++ .../policy/overloaded/bfloat16/vloxseg5ei16.c | 226 + .../policy/overloaded/bfloat16/vloxseg6ei16.c | 238 ++ .../policy/overloaded/bfloat16/vloxseg7ei16.c | 250 ++ .../policy/overloaded/bfloat16/vloxseg8ei16.c | 262 ++ .../policy/overloaded/bfloat16/vlse16.c | 291 ++ .../policy/overloaded/bfloat16/vlseg2e16.c | 275 ++ .../policy/overloaded/bfloat16/vlseg2e16ff.c | 419 ++ .../policy/overloaded/bfloat16/vlseg3e16.c | 239 ++ .../policy/overloaded/bfloat16/vlseg3e16ff.c | 386 ++ .../policy/overloaded/bfloat16/vlseg4e16.c | 255 ++ .../policy/overloaded/bfloat16/vlseg4e16ff.c | 434 ++ .../policy/overloaded/bfloat16/vlseg5e16.c | 207 + .../policy/overloaded/bfloat16/vlseg5e16ff.c | 365 ++ .../policy/overloaded/bfloat16/vlseg6e16.c | 219 + .../policy/overloaded/bfloat16/vlseg6e16ff.c | 401 ++ .../policy/overloaded/bfloat16/vlseg7e16.c | 231 ++ .../policy/overloaded/bfloat16/vlseg7e16ff.c | 437 ++ .../policy/overloaded/bfloat16/vlseg8e16.c | 243 ++ .../policy/overloaded/bfloat16/vlseg8e16ff.c | 473 +++ .../policy/overloaded/bfloat16/vlsseg2e16.c | 296 ++ .../policy/overloaded/bfloat16/vlsseg3e16.c | 256 ++ .../policy/overloaded/bfloat16/vlsseg4e16.c | 272 ++ .../policy/overloaded/bfloat16/vlsseg5e16.c | 220 + .../policy/overloaded/bfloat16/vlsseg6e16.c | 232 ++ .../policy/overloaded/bfloat16/vlsseg7e16.c | 244 ++ .../policy/overloaded/bfloat16/vlsseg8e16.c | 256 ++ .../policy/overloaded/bfloat16/vluxei16.c | 291 ++ .../policy/overloaded/bfloat16/vluxseg2ei16.c | 306 ++ .../policy/overloaded/bfloat16/vluxseg3ei16.c | 264 ++ .../policy/overloaded/bfloat16/vluxseg4ei16.c | 280 ++ .../policy/overloaded/bfloat16/vluxseg5ei16.c | 226 + .../policy/overloaded/bfloat16/vluxseg6ei16.c | 238 ++ .../policy/overloaded/bfloat16/vluxseg7ei16.c | 250 ++ .../policy/overloaded/bfloat16/vluxseg8ei16.c | 262 ++ .../policy/overloaded/vaesdf.c | 10 - .../policy/overloaded/vaesdm.c | 10 - .../policy/overloaded/vaesef.c | 10 - .../policy/overloaded/vaesem.c | 10 - .../policy/overloaded/vaesz.c | 10 - .../policy/overloaded/vsm4r.c | 10 - .../SystemZ/builtins-systemz-zvector.c | 48 +- .../SystemZ/builtins-systemz-zvector2.c | 16 +- clang/test/CodeGen/X86/ms-x86-intrinsics.c | 8 +- .../acle_sve2p1_fp_reduce.c | 12 +- .../CodeGen/arm-bf16-convert-intrinsics.c | 9 +- clang/test/CodeGen/attr-counted-by.c | 72 +- clang/test/CodeGen/builtins-reduction-math.c | 53 + clang/test/CodeGen/builtins-wasm.c | 2 +- clang/test/CodeGen/ms-intrinsics-other.c | 20 +- clang/test/CodeGen/ms-intrinsics.c | 8 +- clang/test/CodeGen/ms-mixed-ptr-sizes.c | 8 +- clang/test/CodeGenCXX/blocks.cpp | 4 +- .../CodeGenCXX/control-flow-in-stmt-expr.cpp | 522 +++ .../CodeGenCXX/dependent-template-alias.cpp | 21 + clang/test/CodeGenCXX/pragma-gcc-unroll.cpp | 30 + clang/test/CodeGenCXX/pragma-unroll.cpp | 52 + clang/test/CodeGenCoroutines/coro-await.cpp | 12 +- clang/test/CodeGenCoroutines/coro-dwarf.cpp | 4 +- .../coro-suspend-cleanups.cpp | 93 + clang/test/CodeGenCoroutines/pr65054.cpp | 2 +- .../test/CodeGenObjC/arc-blocks-exceptions.m | 15 +- clang/test/CodeGenObjC/arc-blocks.m | 4 +- clang/test/CodeGenObjCXX/msabi-stret-arm64.mm | 77 + .../CodeGenOpenCL/builtins-generic-amdgcn.cl | 4 +- clang/test/Driver/aarch64-mcpu.c | 6 + clang/test/Driver/amdgpu-toolchain.c | 4 + clang/test/Driver/cl-options.c | 4 + clang/test/Driver/claim-unused.c | 3 - clang/test/Driver/default-denormal-fp-math.c | 9 - clang/test/Driver/fast-math.c | 333 +- clang/test/Driver/fp-model.c | 5 +- clang/test/Driver/gcc-param.c | 2 + .../test/Driver/hlsl-lang-targets-spirv.hlsl | 1 + clang/test/Driver/integrated-as.c | 2 +- clang/test/Driver/linux-ld.c | 71 +- clang/test/Driver/riscv-arch.c | 6 +- clang/test/Driver/sanitizer-ld.c | 14 + clang/test/Driver/wasm-features.c | 6 + .../ExtractAPI/anonymous_record_no_typedef.c | 565 +-- clang/test/ExtractAPI/availability.c | 529 +-- clang/test/ExtractAPI/enum.c | 12 +- clang/test/ExtractAPI/function_noexcepts.cpp | 18 +- clang/test/ExtractAPI/methods.cpp | 6 +- clang/test/ExtractAPI/objc_block.m | 48 +- .../ExtractAPI/typedef_anonymous_record.c | 4 +- clang/test/ExtractAPI/typedef_struct_enum.c | 2 +- clang/test/Frontend/ast-dump-on-llvm.ll | 29 + clang/test/Headers/wasm.c | 2 +- clang/test/Interpreter/fail.cpp | 21 +- clang/test/Lexer/cxx-features.cpp | 2 +- .../update_consecutive_macro_address_space.c | 13 +- clang/test/Misc/cc1as-relax-all.s | 13 + clang/test/Misc/target-invalid-cpu-note.c | 4 +- clang/test/Modules/pr88400.cppm | 61 + ...e-non-affecting-module-map-files-textual.c | 46 + clang/test/OpenMP/task_depend_messages.cpp | 2 +- clang/test/Parser/cxx1z-decomposition.cpp | 63 +- .../cxx2a-constrained-template-param.cpp | 20 +- clang/test/Parser/pragma-unroll.cpp | 29 + .../ParserOpenACC/parse-cache-construct.cpp | 6 +- clang/test/ParserOpenACC/parse-clauses.c | 4 +- .../Preprocessor/hardware_interference.cpp | 17 + clang/test/Preprocessor/init-aarch64.c | 12 +- clang/test/Preprocessor/init.c | 49 +- .../Preprocessor/predefined-macros-hlsl.hlsl | 23 +- .../test/Preprocessor/predefined-win-macros.c | 6 +- .../test/Preprocessor/riscv-target-features.c | 13 +- .../test/Preprocessor/wasm-target-features.c | 228 +- .../Sema/aarch64-incompat-sm-builtin-calls.c | 12 +- clang/test/Sema/aarch64-sme-func-attrs.c | 48 +- clang/test/Sema/constant_builtins_vector.cpp | 723 ++++ clang/test/Sema/convertvector.c | 3 + ...xx1z-class-template-argument-deduction.cpp | 11 +- clang/test/SemaCXX/cxx2a-consteval.cpp | 20 + .../test/SemaCXX/template-specialization.cpp | 28 + clang/test/SemaCXX/type-traits.cpp | 28 + clang/test/SemaCXX/unused.cpp | 12 +- clang/test/SemaObjC/format-strings-oslog.m | 5 +- clang/test/SemaOpenCL/vec_step.cl | 2 +- clang/test/TestRunner.sh | 13 - clang/tools/c-index-test/c-index-test.c | 54 +- clang/tools/clang-installapi/Options.cpp | 2 - clang/tools/clang-repl/ClangRepl.cpp | 17 +- clang/tools/driver/cc1_main.cpp | 2 +- clang/tools/driver/cc1as_main.cpp | 1 + clang/tools/libclang/CIndex.cpp | 4 +- clang/tools/libclang/CXCursor.cpp | 4 +- clang/tools/libclang/CXSourceLocation.cpp | 3 +- .../Analysis/FlowSensitive/TestingSupport.h | 4 +- .../Analysis/FlowSensitive/TransferTest.cpp | 187 +- clang/unittests/Format/FormatTest.cpp | 64 +- clang/unittests/Format/SortIncludesTest.cpp | 122 +- clang/unittests/Format/TokenAnnotatorTest.cpp | 77 + clang/unittests/libclang/LibclangTest.cpp | 31 + clang/utils/TableGen/ClangAttrEmitter.cpp | 48 +- clang/utils/TableGen/RISCVVEmitter.cpp | 1 + clang/www/cxx_dr_status.html | 563 ++- clang/www/cxx_status.html | 4 +- clang/www/make_cxx_dr_status | 8 +- compiler-rt/lib/fuzzer/build.sh | 2 +- .../sanitizer_symbolizer_markup.cpp | 10 +- .../sanitizer_symbolizer_markup_constants.h | 6 +- .../lib/scudo/standalone/allocator_config.def | 2 + compiler-rt/lib/scudo/standalone/combined.h | 3 + compiler-rt/lib/scudo/standalone/flags.inc | 2 +- .../lib/scudo/standalone/mem_map_fuchsia.cpp | 41 +- compiler-rt/lib/scudo/standalone/primary32.h | 4 + compiler-rt/lib/scudo/standalone/primary64.h | 7 +- compiler-rt/lib/scudo/standalone/secondary.h | 3 + .../lib/scudo/standalone/wrappers_c.inc | 10 +- compiler-rt/test/CMakeLists.txt | 3 + .../test/asan/TestCases/Darwin/odr-lto.cpp | 2 +- compiler-rt/test/ctx_profile/CMakeLists.txt | 21 + .../test/ctx_profile/Unit/lit.site.cfg.py.in | 28 + compiler-rt/test/memprof/CMakeLists.txt | 13 + .../test/memprof/Unit/lit.site.cfg.py.in | 31 + .../modules/AddFlangOffloadRuntime.cmake | 9 + flang/docs/FlangDriver.md | 32 +- flang/docs/Preprocessing.md | 3 + flang/include/flang/Common/visit.h | 8 +- flang/include/flang/Evaluate/call.h | 7 +- flang/include/flang/Lower/Allocatable.h | 4 +- flang/include/flang/Lower/Mangler.h | 2 +- .../flang/Optimizer/Analysis/TBAAForest.h | 2 +- .../flang/Optimizer/Builder/BoxValue.h | 20 +- .../include/flang/Optimizer/Builder/Factory.h | 12 +- .../flang/Optimizer/Builder/HLFIRTools.h | 14 +- .../flang/Optimizer/Builder/IntrinsicCall.h | 6 +- .../Optimizer/Builder/PPCIntrinsicCall.h | 6 +- .../Builder/Runtime/EnvironmentDefaults.h | 3 +- .../flang/Optimizer/Builder/Runtime/Main.h | 28 + .../Dialect/CanonicalizationPatterns.td | 23 +- .../include/flang/Optimizer/Dialect/FIROps.td | 12 +- .../include/flang/Optimizer/Dialect/FIRType.h | 74 +- .../flang/Optimizer/Dialect/FIRTypes.td | 2 +- .../Dialect/FortranVariableInterface.td | 10 +- .../flang/Optimizer/HLFIR/HLFIRDialect.h | 20 +- flang/include/flang/Optimizer/Support/Utils.h | 4 +- .../flang/Optimizer/Transforms/Passes.h | 19 +- .../flang/Optimizer/Transforms/Passes.td | 36 +- flang/include/flang/Parser/parse-tree.h | 3 +- flang/include/flang/Parser/preprocessor.h | 1 + flang/include/flang/Runtime/descriptor.h | 1 + flang/include/flang/Runtime/numeric.h | 8 + flang/include/flang/Tools/CLOptions.inc | 93 +- flang/include/flang/Tools/PointerModels.h | 4 +- flang/lib/Evaluate/intrinsics.cpp | 4 +- flang/lib/Evaluate/type.cpp | 2 +- flang/lib/Frontend/FrontendActions.cpp | 5 +- flang/lib/Lower/Allocatable.cpp | 24 +- flang/lib/Lower/Bridge.cpp | 78 +- flang/lib/Lower/CallInterface.cpp | 6 +- flang/lib/Lower/ConvertArrayConstructor.cpp | 11 +- flang/lib/Lower/ConvertCall.cpp | 56 +- flang/lib/Lower/ConvertConstant.cpp | 23 +- flang/lib/Lower/ConvertExpr.cpp | 188 +- flang/lib/Lower/ConvertExprToHLFIR.cpp | 28 +- .../lib/Lower/ConvertProcedureDesignator.cpp | 6 +- flang/lib/Lower/ConvertVariable.cpp | 34 +- flang/lib/Lower/CustomIntrinsicCall.cpp | 35 +- flang/lib/Lower/DirectivesCommon.h | 24 +- flang/lib/Lower/HlfirIntrinsics.cpp | 4 +- flang/lib/Lower/HostAssociations.cpp | 20 +- flang/lib/Lower/IO.cpp | 55 +- flang/lib/Lower/OpenACC.cpp | 36 +- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 8 +- .../lib/Lower/OpenMP/DataSharingProcessor.cpp | 46 +- flang/lib/Lower/OpenMP/OpenMP.cpp | 149 +- flang/lib/Lower/OpenMP/ReductionProcessor.cpp | 199 +- flang/lib/Lower/VectorSubscripts.cpp | 2 +- .../lib/Optimizer/Analysis/AliasAnalysis.cpp | 4 +- flang/lib/Optimizer/Builder/BoxValue.cpp | 4 +- flang/lib/Optimizer/Builder/CMakeLists.txt | 1 + flang/lib/Optimizer/Builder/Character.cpp | 41 +- flang/lib/Optimizer/Builder/Complex.cpp | 3 +- flang/lib/Optimizer/Builder/FIRBuilder.cpp | 109 +- flang/lib/Optimizer/Builder/HLFIRTools.cpp | 78 +- flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 140 +- flang/lib/Optimizer/Builder/MutableBox.cpp | 35 +- .../Optimizer/Builder/PPCIntrinsicCall.cpp | 44 +- .../Optimizer/Builder/Runtime/Allocatable.cpp | 2 +- .../Optimizer/Builder/Runtime/Character.cpp | 8 +- .../Builder/Runtime/EnvironmentDefaults.cpp | 7 +- .../Optimizer/Builder/Runtime/Intrinsics.cpp | 6 +- flang/lib/Optimizer/Builder/Runtime/Main.cpp | 62 + .../lib/Optimizer/Builder/Runtime/Ragged.cpp | 3 +- .../Optimizer/Builder/Runtime/Reduction.cpp | 20 +- .../lib/Optimizer/CodeGen/BoxedProcedure.cpp | 16 +- flang/lib/Optimizer/CodeGen/CGOps.cpp | 14 +- flang/lib/Optimizer/CodeGen/CodeGen.cpp | 211 +- flang/lib/Optimizer/CodeGen/FIROpPatterns.cpp | 21 +- flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 13 +- flang/lib/Optimizer/CodeGen/TBAABuilder.cpp | 2 +- flang/lib/Optimizer/CodeGen/Target.cpp | 4 +- flang/lib/Optimizer/CodeGen/TargetRewrite.cpp | 21 +- flang/lib/Optimizer/CodeGen/TypeConverter.cpp | 18 +- flang/lib/Optimizer/Dialect/FIRAttr.cpp | 14 +- flang/lib/Optimizer/Dialect/FIROps.cpp | 310 +- flang/lib/Optimizer/Dialect/FIRType.cpp | 141 +- .../Dialect/FortranVariableInterface.cpp | 11 +- flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp | 30 +- flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp | 192 +- .../HLFIR/Transforms/BufferizeHLFIR.cpp | 29 +- .../HLFIR/Transforms/ConvertToFIR.cpp | 47 +- .../HLFIR/Transforms/LowerHLFIRIntrinsics.cpp | 2 +- .../LowerHLFIROrderedAssignments.cpp | 2 +- .../Transforms/OptimizedBufferization.cpp | 12 +- .../Transforms/SimplifyHLFIRIntrinsics.cpp | 3 +- .../Optimizer/Transforms/AbstractResult.cpp | 16 +- .../lib/Optimizer/Transforms/AddDebugInfo.cpp | 86 +- .../Optimizer/Transforms/AffineDemotion.cpp | 9 +- .../Optimizer/Transforms/AffinePromotion.cpp | 11 +- .../Optimizer/Transforms/ArrayValueCopy.cpp | 30 +- flang/lib/Optimizer/Transforms/CMakeLists.txt | 1 + .../Transforms/CharacterConversion.cpp | 11 +- .../Transforms/ControlFlowConverter.cpp | 26 +- .../Optimizer/Transforms/LoopVersioning.cpp | 6 +- .../Optimizer/Transforms/MemoryAllocation.cpp | 32 +- .../Transforms/OMPFunctionFiltering.cpp | 11 + .../Transforms/PolymorphicOpConversion.cpp | 38 +- .../Transforms/SimplifyIntrinsics.cpp | 64 +- .../Transforms/SimplifyRegionLite.cpp | 4 - .../lib/Optimizer/Transforms/StackArrays.cpp | 6 +- flang/lib/Parser/Fortran-parsers.cpp | 3 +- flang/lib/Parser/prescan.cpp | 18 +- flang/lib/Parser/prescan.h | 1 + flang/lib/Semantics/check-call.cpp | 6 +- flang/lib/Semantics/check-declarations.cpp | 4 - flang/lib/Semantics/check-omp-structure.cpp | 14 +- flang/lib/Semantics/check-omp-structure.h | 4 +- flang/lib/Semantics/expression.cpp | 4 +- flang/lib/Semantics/program-tree.cpp | 86 +- flang/lib/Semantics/program-tree.h | 30 +- flang/lib/Semantics/resolve-names.cpp | 19 +- flang/runtime/CMakeLists.txt | 2 +- flang/runtime/FortranMain/CMakeLists.txt | 23 - flang/runtime/FortranMain/Fortran_main.c | 23 - flang/runtime/edit-output.cpp | 19 +- flang/runtime/environment.cpp | 2 + flang/runtime/file.cpp | 12 +- flang/runtime/namelist.cpp | 2 +- flang/runtime/numeric.cpp | 79 +- flang/runtime/unit.cpp | 2 + flang/runtime/utf.cpp | 2 + flang/test/CMakeLists.txt | 1 - flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 17 +- flang/test/Driver/driver-help-hidden.f90 | 1 - flang/test/Driver/driver-help.f90 | 283 -- flang/test/Driver/dynamic-linker.f90 | 2 - flang/test/Driver/emit-mlir.f90 | 10 + flang/test/Driver/linker-flags.f90 | 8 - .../test/Driver/mlir-debug-pass-pipeline.f90 | 21 +- flang/test/Driver/mlir-pass-pipeline.f90 | 21 +- .../test/Driver/msvc-dependent-lib-flags.f90 | 4 - flang/test/Driver/no-duplicate-main.f90 | 2 - flang/test/Fir/array-value-copy-2.fir | 4 +- flang/test/Fir/basic-program.fir | 23 +- .../Fir/convert-to-llvm-openmp-and-fir.fir | 110 +- flang/test/Fir/loop01.fir | 2 +- flang/test/Fir/loop02.fir | 4 +- flang/test/Lower/CUDA/cuda-allocatable.cuf | 30 + flang/test/Lower/CUDA/cuda-data-transfer.cuf | 42 +- flang/test/Lower/HLFIR/calls-f77.f90 | 13 + .../test/Lower/HLFIR/internal-procedures.f90 | 27 + flang/test/Lower/Intrinsics/shape.f90 | 74 + flang/test/Lower/OpenACC/acc-declare.f90 | 5 + flang/test/Lower/OpenMP/FIR/array-bounds.f90 | 121 - .../test/Lower/OpenMP/FIR/atomic-capture.f90 | 119 - flang/test/Lower/OpenMP/FIR/atomic-read.f90 | 80 - flang/test/Lower/OpenMP/FIR/atomic-update.f90 | 141 - flang/test/Lower/OpenMP/FIR/atomic-write.f90 | 77 - flang/test/Lower/OpenMP/FIR/copyin.f90 | 352 -- flang/test/Lower/OpenMP/FIR/critical.f90 | 38 - .../Lower/OpenMP/FIR/declare-target-data.f90 | 88 - .../FIR/declare-target-func-and-subr.f90 | 178 - ...arget-implicit-func-and-subr-cap-enter.f90 | 192 - ...lare-target-implicit-func-and-subr-cap.f90 | 218 - .../test/Lower/OpenMP/FIR/default-clause.f90 | 281 -- .../delayed-privatization-firstprivate.f90 | 32 - .../FIR/delayed-privatization-private.f90 | 41 - .../OpenMP/FIR/firstprivate-commonblock.f90 | 30 - flang/test/Lower/OpenMP/FIR/flush.f90 | 45 - flang/test/Lower/OpenMP/FIR/if-clause.f90 | 496 --- flang/test/Lower/OpenMP/FIR/is-device.f90 | 14 - .../OpenMP/FIR/lastprivate-commonblock.f90 | 46 - flang/test/Lower/OpenMP/FIR/location.f90 | 68 - flang/test/Lower/OpenMP/FIR/loop-combined.f90 | 83 - .../Lower/OpenMP/FIR/map-component-ref.f90 | 33 - flang/test/Lower/OpenMP/FIR/master.f90 | 100 - .../FIR/omp-declare-target-program-var.f90 | 12 - flang/test/Lower/OpenMP/FIR/omp-is-gpu.f90 | 16 - .../test/Lower/OpenMP/FIR/ordered-threads.f90 | 40 - .../parallel-firstprivate-clause-scalar.f90 | 159 - .../parallel-lastprivate-clause-scalar.f90 | 237 -- .../FIR/parallel-private-clause-fixes.f90 | 81 - .../OpenMP/FIR/parallel-private-clause.f90 | 381 -- .../FIR/parallel-reduction-add-byref.f90 | 117 - .../OpenMP/FIR/parallel-reduction-add.f90 | 105 - .../Lower/OpenMP/FIR/parallel-sections.f90 | 65 - .../OpenMP/FIR/parallel-wsloop-firstpriv.f90 | 61 - .../test/Lower/OpenMP/FIR/parallel-wsloop.f90 | 277 -- flang/test/Lower/OpenMP/FIR/parallel.f90 | 211 - .../Lower/OpenMP/FIR/pre-fir-tree-loop.f90 | 70 - .../test/Lower/OpenMP/FIR/pre-fir-tree01.f90 | 19 - .../Lower/OpenMP/FIR/private-commonblock.f90 | 109 - .../test/Lower/OpenMP/FIR/requires-common.f90 | 19 - .../Lower/OpenMP/FIR/requires-notarget.f90 | 14 - flang/test/Lower/OpenMP/FIR/requires.f90 | 14 - flang/test/Lower/OpenMP/FIR/rtl-flags.f90 | 39 - flang/test/Lower/OpenMP/FIR/sections-pft.f90 | 91 - flang/test/Lower/OpenMP/FIR/sections.f90 | 288 -- flang/test/Lower/OpenMP/FIR/simd.f90 | 175 - .../test/Lower/OpenMP/FIR/simple-barrier.f90 | 6 - flang/test/Lower/OpenMP/FIR/single.f90 | 123 - .../Lower/OpenMP/FIR/stop-stmt-in-region.f90 | 151 - flang/test/Lower/OpenMP/FIR/target.f90 | 550 --- .../Lower/OpenMP/FIR/target_cpu_features.f90 | 19 - flang/test/Lower/OpenMP/FIR/task.f90 | 237 -- flang/test/Lower/OpenMP/FIR/taskgroup.f90 | 21 - flang/test/Lower/OpenMP/FIR/taskwait.f90 | 12 - flang/test/Lower/OpenMP/FIR/taskyield.f90 | 12 - flang/test/Lower/OpenMP/FIR/teams.f90 | 117 - .../threadprivate-char-array-chararray.f90 | 46 - .../OpenMP/FIR/threadprivate-commonblock.f90 | 91 - .../threadprivate-integer-different-kinds.f90 | 67 - .../OpenMP/FIR/threadprivate-non-global.f90 | 91 - .../FIR/threadprivate-pointer-allocatable.f90 | 51 - ...ivate-real-logical-complex-derivedtype.f90 | 58 - .../FIR/threadprivate-use-association-2.f90 | 39 - .../FIR/threadprivate-use-association.f90 | 74 - flang/test/Lower/OpenMP/FIR/unstructured.f90 | 344 -- flang/test/Lower/OpenMP/FIR/wsloop-chunks.f90 | 75 - .../test/Lower/OpenMP/FIR/wsloop-collapse.f90 | 63 - .../Lower/OpenMP/FIR/wsloop-monotonic.f90 | 34 - .../Lower/OpenMP/FIR/wsloop-nonmonotonic.f90 | 36 - .../test/Lower/OpenMP/FIR/wsloop-ordered.f90 | 40 - .../OpenMP/FIR/wsloop-reduction-add-byref.f90 | 392 -- .../Lower/OpenMP/FIR/wsloop-reduction-add.f90 | 367 -- .../FIR/wsloop-reduction-iand-byref.f90 | 46 - .../OpenMP/FIR/wsloop-reduction-iand.f90 | 36 - .../FIR/wsloop-reduction-ieor-byref.f90 | 45 - .../OpenMP/FIR/wsloop-reduction-ieor.f90 | 36 - .../OpenMP/FIR/wsloop-reduction-ior-byref.f90 | 45 - .../Lower/OpenMP/FIR/wsloop-reduction-ior.f90 | 36 - .../wsloop-reduction-logical-eqv-byref.f90 | 187 - .../FIR/wsloop-reduction-logical-eqv.f90 | 181 - .../wsloop-reduction-logical-neqv-byref.f90 | 189 - .../FIR/wsloop-reduction-logical-neqv.f90 | 183 - .../OpenMP/FIR/wsloop-reduction-max-byref.f90 | 90 - .../Lower/OpenMP/FIR/wsloop-reduction-max.f90 | 79 - .../OpenMP/FIR/wsloop-reduction-min-byref.f90 | 91 - .../Lower/OpenMP/FIR/wsloop-reduction-min.f90 | 80 - flang/test/Lower/OpenMP/FIR/wsloop-simd.f90 | 34 - .../test/Lower/OpenMP/FIR/wsloop-variable.f90 | 173 - flang/test/Lower/OpenMP/FIR/wsloop.f90 | 72 - .../Todo/omp-default-clause-inner-loop.f90 | 5 +- .../OpenMP/Todo/reduction-allocatable.f90 | 21 - .../OpenMP/cfg-conversion-omp.private.f90 | 54 + flang/test/Lower/OpenMP/copyin.f90 | 28 +- .../Lower/OpenMP/default-clause-byref.f90 | 5 +- .../OpenMP/default-clause-implied-do-fix.f90 | 11 + flang/test/Lower/OpenMP/default-clause.f90 | 5 +- .../Lower/OpenMP/function-filtering-3.f90 | 34 + flang/test/Lower/OpenMP/hlfir-wsloop.f90 | 12 +- flang/test/Lower/OpenMP/if-clause.f90 | 6 +- .../Lower/OpenMP/lastprivate-commonblock.f90 | 59 +- flang/test/Lower/OpenMP/lastprivate-iv.f90 | 90 +- flang/test/Lower/OpenMP/location.f90 | 17 +- .../parallel-lastprivate-clause-scalar.f90 | 48 +- .../OpenMP/parallel-private-clause-fixes.f90 | 49 +- .../Lower/OpenMP/parallel-private-clause.f90 | 106 +- .../parallel-reduction-allocatable-array.f90 | 119 + .../OpenMP/parallel-reduction-array-lb.f90 | 90 + .../Lower/OpenMP/parallel-reduction-array.f90 | 7 +- .../OpenMP/parallel-reduction-array2.f90 | 10 +- .../test/Lower/OpenMP/parallel-reduction3.f90 | 59 +- .../OpenMP/parallel-wsloop-firstpriv.f90 | 10 +- flang/test/Lower/OpenMP/parallel-wsloop.f90 | 138 +- flang/test/Lower/OpenMP/simd.f90 | 5 +- .../test/Lower/OpenMP/stop-stmt-in-region.f90 | 39 +- flang/test/Lower/OpenMP/target.f90 | 8 +- ...ivate-real-logical-complex-derivedtype.f90 | 1 + flang/test/Lower/OpenMP/unstructured.f90 | 199 +- .../use-device-ptr-to-use-device-addr.f90 | 5 +- flang/test/Lower/OpenMP/wsloop-chunks.f90 | 47 +- flang/test/Lower/OpenMP/wsloop-collapse.f90 | 29 +- flang/test/Lower/OpenMP/wsloop-monotonic.f90 | 18 +- .../test/Lower/OpenMP/wsloop-nonmonotonic.f90 | 19 +- flang/test/Lower/OpenMP/wsloop-ordered.f90 | 18 +- .../OpenMP/wsloop-reduction-add-byref.f90 | 219 +- .../wsloop-reduction-add-hlfir-byref.f90 | 18 +- .../OpenMP/wsloop-reduction-add-hlfir.f90 | 18 +- .../Lower/OpenMP/wsloop-reduction-add.f90 | 219 +- .../OpenMP/wsloop-reduction-allocatable.f90 | 97 + .../wsloop-reduction-array-assumed-shape.f90 | 44 +- .../Lower/OpenMP/wsloop-reduction-array.f90 | 42 +- .../Lower/OpenMP/wsloop-reduction-array2.f90 | 58 +- .../OpenMP/wsloop-reduction-iand-byref.f90 | 24 +- .../Lower/OpenMP/wsloop-reduction-iand.f90 | 24 +- .../OpenMP/wsloop-reduction-ieor-byref.f90 | 6 +- .../Lower/OpenMP/wsloop-reduction-ieor.f90 | 6 +- .../OpenMP/wsloop-reduction-ior-byref.f90 | 24 +- .../Lower/OpenMP/wsloop-reduction-ior.f90 | 24 +- .../wsloop-reduction-logical-and-byref.f90 | 134 +- .../OpenMP/wsloop-reduction-logical-and.f90 | 134 +- .../wsloop-reduction-logical-eqv-byref.f90 | 134 +- .../OpenMP/wsloop-reduction-logical-eqv.f90 | 134 +- .../wsloop-reduction-logical-neqv-byref.f90 | 134 +- .../OpenMP/wsloop-reduction-logical-neqv.f90 | 134 +- .../wsloop-reduction-logical-or-byref.f90 | 134 +- .../OpenMP/wsloop-reduction-logical-or.f90 | 134 +- .../OpenMP/wsloop-reduction-max-byref.f90 | 90 +- .../wsloop-reduction-max-hlfir-byref.f90 | 26 +- .../OpenMP/wsloop-reduction-max-hlfir.f90 | 26 +- .../Lower/OpenMP/wsloop-reduction-max.f90 | 90 +- .../OpenMP/wsloop-reduction-min-byref.f90 | 92 +- .../Lower/OpenMP/wsloop-reduction-min.f90 | 92 +- .../Lower/OpenMP/wsloop-reduction-min2.f90 | 16 +- .../OpenMP/wsloop-reduction-mul-byref.f90 | 212 +- .../Lower/OpenMP/wsloop-reduction-mul.f90 | 212 +- .../Lower/OpenMP/wsloop-reduction-multi.f90 | 49 +- flang/test/Lower/OpenMP/wsloop-simd.f90 | 29 +- .../test/Lower/OpenMP/wsloop-unstructured.f90 | 39 +- flang/test/Lower/OpenMP/wsloop-variable.f90 | 167 +- flang/test/Lower/OpenMP/wsloop.f90 | 72 +- flang/test/Parser/unrecognized-dir.f90 | 8 +- .../test/Preprocessing/backslash-contin1.F90 | 8 + .../test/Semantics/OpenMP/firstprivate02.f90 | 20 + flang/test/Semantics/OpenMP/lastprivate03.f90 | 24 + .../Semantics/OpenMP/parallel-private01.f90 | 2 +- .../Semantics/OpenMP/parallel-private02.f90 | 2 +- .../Semantics/OpenMP/parallel-private03.f90 | 2 +- .../Semantics/OpenMP/parallel-private04.f90 | 2 +- .../Semantics/OpenMP/parallel-sections01.f90 | 8 +- .../Semantics/OpenMP/parallel-shared01.f90 | 2 +- .../Semantics/OpenMP/parallel-shared02.f90 | 2 +- .../Semantics/OpenMP/parallel-shared03.f90 | 2 +- .../Semantics/OpenMP/parallel-shared04.f90 | 2 +- flang/test/Semantics/arg-convert.f90 | 16 + flang/test/Semantics/cuf02.cuf | 18 +- flang/test/Semantics/declarations03.f90 | 13 +- .../Transforms/debug-line-table-inc-file.fir | 4 +- flang/test/Transforms/debug-line-table.fir | 8 +- .../omp-reduction-cfg-conversion.fir | 2 +- flang/tools/flang-driver/CMakeLists.txt | 1 - .../Optimizer/Builder/ComplexTest.cpp | 2 +- .../Optimizer/Builder/DoLoopHelperTest.cpp | 2 +- .../Optimizer/Builder/FIRBuilderTest.cpp | 48 +- flang/unittests/Optimizer/RTBuilder.cpp | 2 +- .../unittests/Runtime/NumericalFormatTest.cpp | 17 + flang/unittests/Runtime/RuntimeCrashTest.cpp | 10 - libc/config/linux/syscall_numbers.h.inc | 4 + libc/docs/index.rst | 1 + libc/docs/setjmp.rst | 16 + libc/include/assert.h.def | 1 + libc/include/llvm-libc-macros/CMakeLists.txt | 6 + libc/include/llvm-libc-macros/assert-macros.h | 14 + libc/src/sys/stat/linux/chmod.cpp | 7 +- libc/test/UnitTest/CMakeLists.txt | 2 + libc/test/UnitTest/FEnvSafeTest.cpp | 84 + libc/test/UnitTest/FEnvSafeTest.h | 101 + libc/test/include/CMakeLists.txt | 10 + libc/test/include/assert_test.cpp | 15 + libc/test/src/fenv/CMakeLists.txt | 16 + .../test/src/fenv/enabled_exceptions_test.cpp | 18 +- libc/test/src/fenv/exception_flags_test.cpp | 12 +- libc/test/src/fenv/exception_status_test.cpp | 43 +- libc/test/src/fenv/excepts.h | 24 + libc/test/src/fenv/feclearexcept_test.cpp | 21 +- libc/test/src/fenv/feenableexcept_test.cpp | 7 +- libc/test/src/fenv/feholdexcept_test.cpp | 7 +- libc/test/src/fenv/feupdateenv_test.cpp | 5 +- libc/test/src/fenv/getenv_and_setenv_test.cpp | 14 +- libc/test/src/fenv/rounding_mode_test.cpp | 9 +- libc/test/src/math/CeilTest.h | 4 +- libc/test/src/math/CopySignTest.h | 3 +- libc/test/src/math/FAbsTest.h | 4 +- libc/test/src/math/FDimTest.h | 3 +- libc/test/src/math/FMaxTest.h | 4 +- libc/test/src/math/FMinTest.h | 4 +- libc/test/src/math/FModTest.h | 4 +- libc/test/src/math/FloorTest.h | 4 +- libc/test/src/math/FmaTest.h | 3 +- libc/test/src/math/FrexpTest.h | 4 +- libc/test/src/math/HypotTest.h | 3 +- libc/test/src/math/ILogbTest.h | 3 +- libc/test/src/math/LdExpTest.h | 3 +- libc/test/src/math/LogbTest.h | 4 +- libc/test/src/math/ModfTest.h | 4 +- libc/test/src/math/NextAfterTest.h | 3 +- libc/test/src/math/RIntTest.h | 3 +- libc/test/src/math/RemQuoTest.h | 3 +- libc/test/src/math/RoundEvenTest.h | 3 +- libc/test/src/math/RoundTest.h | 4 +- libc/test/src/math/RoundToIntegerTest.h | 6 +- libc/test/src/math/SqrtTest.h | 4 +- libc/test/src/math/TruncTest.h | 4 +- .../exhaustive/fmod_generic_impl_test.cpp | 3 +- libc/test/src/math/smoke/CanonicalizeTest.h | 3 +- libc/test/src/math/smoke/CeilTest.h | 4 +- libc/test/src/math/smoke/CopySignTest.h | 3 +- libc/test/src/math/smoke/FAbsTest.h | 4 +- libc/test/src/math/smoke/FDimTest.h | 3 +- libc/test/src/math/smoke/FMaxTest.h | 4 +- libc/test/src/math/smoke/FMaximumMagNumTest.h | 3 +- libc/test/src/math/smoke/FMaximumMagTest.h | 3 +- libc/test/src/math/smoke/FMaximumNumTest.h | 3 +- libc/test/src/math/smoke/FMaximumTest.h | 3 +- libc/test/src/math/smoke/FMinTest.h | 4 +- libc/test/src/math/smoke/FMinimumMagNumTest.h | 3 +- libc/test/src/math/smoke/FMinimumMagTest.h | 3 +- libc/test/src/math/smoke/FMinimumNumTest.h | 3 +- libc/test/src/math/smoke/FMinimumTest.h | 3 +- libc/test/src/math/smoke/FModTest.h | 4 +- libc/test/src/math/smoke/FloorTest.h | 4 +- libc/test/src/math/smoke/FmaTest.h | 3 +- libc/test/src/math/smoke/FrexpTest.h | 4 +- libc/test/src/math/smoke/FromfpTest.h | 3 +- libc/test/src/math/smoke/FromfpxTest.h | 3 +- libc/test/src/math/smoke/HypotTest.h | 3 +- libc/test/src/math/smoke/ILogbTest.h | 3 +- libc/test/src/math/smoke/LdExpTest.h | 3 +- libc/test/src/math/smoke/LogbTest.h | 4 +- libc/test/src/math/smoke/ModfTest.h | 4 +- libc/test/src/math/smoke/NextAfterTest.h | 3 +- libc/test/src/math/smoke/NextDownTest.h | 3 +- libc/test/src/math/smoke/NextTowardTest.h | 3 +- libc/test/src/math/smoke/NextUpTest.h | 3 +- libc/test/src/math/smoke/RIntTest.h | 3 +- libc/test/src/math/smoke/RemQuoTest.h | 3 +- libc/test/src/math/smoke/RoundEvenTest.h | 3 +- libc/test/src/math/smoke/RoundTest.h | 4 +- libc/test/src/math/smoke/RoundToIntegerTest.h | 6 +- libc/test/src/math/smoke/SqrtTest.h | 4 +- libc/test/src/math/smoke/TruncTest.h | 4 +- libc/test/src/math/smoke/UfromfpTest.h | 3 +- libc/test/src/math/smoke/UfromfpxTest.h | 3 +- libc/test/src/math/smoke/nan_test.cpp | 3 +- libc/test/src/math/smoke/nanf128_test.cpp | 3 +- libc/test/src/math/smoke/nanf_test.cpp | 3 +- libc/test/src/math/smoke/nanl_test.cpp | 3 +- libc/utils/docgen/setjmp.json | 15 + libclc/cmake/modules/AddLibclc.cmake | 19 +- libcxx/CMakeLists.txt | 2 +- libcxx/benchmarks/CMakeLists.txt | 1 + ...ormat_spec_string_unicode_escape.bench.cpp | 303 ++ libcxx/cmake/caches/Generic-cxx20.cmake | 1 - libcxx/cmake/caches/Generic-cxx23.cmake | 1 - libcxx/cmake/caches/Generic-cxx26.cmake | 1 - .../Generic-hardening-mode-extensive.cmake | 1 - .../cmake/caches/Generic-no-exceptions.cmake | 1 - .../caches/Generic-no-experimental.cmake | 1 - .../cmake/caches/Generic-no-filesystem.cmake | 1 - .../caches/Generic-no-localization.cmake | 1 - .../caches/Generic-no-random_device.cmake | 1 - libcxx/cmake/caches/Generic-no-threads.cmake | 1 - libcxx/cmake/caches/Generic-no-unicode.cmake | 1 - .../caches/Generic-no-wide-characters.cmake | 1 - libcxx/docs/BuildingLibcxx.rst | 2 +- libcxx/docs/Modules.rst | 77 +- libcxx/docs/ReleaseNotes/19.rst | 4 + libcxx/docs/Status/Cxx23.rst | 1 - libcxx/docs/Status/Cxx23Papers.csv | 4 +- libcxx/docs/Status/Cxx2cIssues.csv | 6 +- libcxx/docs/Status/FormatIssues.csv | 2 +- libcxx/docs/Status/RangesMajorFeatures.csv | 2 +- libcxx/include/__algorithm/find.h | 20 +- libcxx/include/__algorithm/ranges_find.h | 4 +- libcxx/include/__availability | 415 +- libcxx/include/__chrono/formatter.h | 3 + .../include/__format/escaped_output_table.h | 1648 ++++---- libcxx/include/__format/write_escaped.h | 28 +- .../include/__numeric/saturation_arithmetic.h | 41 +- libcxx/include/__ranges/range_adaptor.h | 53 +- libcxx/include/__ranges/to.h | 3 +- libcxx/include/__string/char_traits.h | 4 +- .../include/__string/constexpr_c_functions.h | 2 +- libcxx/include/__type_traits/datasizeof.h | 47 +- libcxx/include/__utility/no_destroy.h | 29 +- libcxx/include/format | 2 + libcxx/include/ranges | 5 + libcxx/include/streambuf | 6 + libcxx/include/variant | 104 +- libcxx/modules/std.compat/cstdlib.inc | 2 +- libcxx/modules/std/ranges.inc | 15 +- libcxx/src/time_zone.cpp | 19 +- .../test/libcxx/transitive_includes/cxx20.csv | 1 + .../type_traits/datasizeof.compile.pass.cpp | 14 +- .../no_unique_address.compile.pass.cpp | 22 +- .../no_unique_address.compile.pass.cpp | 18 +- .../format.string.std/escaped_output.pass.cpp | 102 + .../test/libcxx/utilities/no_destroy.pass.cpp | 31 + .../atomics.types.float/fetch_add.pass.cpp | 1 - .../atomics.types.float/fetch_sub.pass.cpp | 1 - .../operator.minus_equals.pass.cpp | 1 - .../operator.plus_equals.pass.cpp | 1 - .../array/size_and_alignment.compile.pass.cpp | 2 +- .../streambuf/streambuf.cons/copy.pass.cpp | 14 +- .../streambuf.assign/assign.pass.cpp | 14 +- .../streambuf.assign/swap.pass.cpp | 14 +- .../streambuf.get.area/setg.assert.pass.cpp | 68 + .../streambuf.put.area/setp.assert.pass.cpp | 57 + .../hardware_inference_size.compile.pass.cpp | 2 +- .../range_adaptor_closure.pass.cpp | 142 + .../range.utility.conv/to.pass.cpp | 5 + .../time.clock.file/ostream.pass.cpp | 109 + .../time.clock.local/ostream.pass.cpp | 54 + .../sys_time.ostream.pass.cpp | 54 + .../get_info.sys_time.pass.cpp | 76 + .../escaped_output.unicode.pass.cpp | 42 +- libcxx/utils/generate_escaped_output_table.py | 123 +- libcxx/utils/libcxx/header_information.py | 13 +- lld/COFF/MinGW.cpp | 1 - lld/ELF/Arch/RISCV.cpp | 6 +- lld/test/ELF/lto/i386-global-offset-table.ll | 29 + .../ELF/lto/x86-64-global-offset-table.ll | 71 + lld/test/ELF/mips-eh_frame-pic.s | 4 +- lld/test/ELF/riscv-branch.s | 16 +- lld/test/ELF/riscv-call.s | 16 +- lld/test/ELF/riscv-hi20-lo12.s | 24 +- lld/test/ELF/riscv-jal.s | 16 +- lld/test/wasm/init-fini.ll | 2 +- lldb/CMakeLists.txt | 8 + lldb/bindings/interface/SBValueDocstrings.i | 20 + lldb/docs/conf.py | 21 + lldb/docs/index.rst | 2 + lldb/docs/lldb-gdb-remote.txt | 2286 ----------- lldb/docs/lldb-platform-packets.txt | 451 -- lldb/docs/resources/lldbgdbremote.md | 2473 +++++++++++ lldb/docs/resources/lldbplatformpackets.md | 49 + lldb/docs/resources/test.rst | 6 +- lldb/include/lldb/API/SBDebugger.h | 7 + lldb/include/lldb/API/SBLineEntry.h | 3 + lldb/include/lldb/API/SBProcess.h | 2 + lldb/include/lldb/API/SBSymbolContextList.h | 1 + lldb/include/lldb/API/SBTarget.h | 5 + lldb/include/lldb/API/SBType.h | 32 + lldb/include/lldb/API/SBValue.h | 3 + lldb/include/lldb/Core/Debugger.h | 2 +- .../include/lldb/Core/ThreadedCommunication.h | 4 +- .../lldb/Interpreter/CommandInterpreter.h | 4 +- lldb/include/lldb/Symbol/CompilerDecl.h | 7 + lldb/include/lldb/Symbol/CompilerType.h | 2 + lldb/include/lldb/Symbol/TypeSystem.h | 9 + lldb/include/lldb/Target/Process.h | 4 +- lldb/include/lldb/Target/Target.h | 4 +- lldb/include/lldb/Target/TargetList.h | 4 +- lldb/include/lldb/Target/Thread.h | 4 +- lldb/include/lldb/Utility/Broadcaster.h | 8 +- lldb/include/lldb/Utility/ProcessInfo.h | 2 +- .../test/tools/lldb-dap/dap_server.py | 21 +- .../test/tools/lldb-dap/lldbdap_testcase.py | 4 +- lldb/source/API/SBCommandInterpreter.cpp | 3 +- lldb/source/API/SBCommunication.cpp | 3 +- lldb/source/API/SBDebugger.cpp | 2 +- lldb/source/API/SBEvent.cpp | 3 +- lldb/source/API/SBLineEntry.cpp | 15 + lldb/source/API/SBProcess.cpp | 12 +- lldb/source/API/SBTarget.cpp | 26 +- lldb/source/API/SBThread.cpp | 2 +- lldb/source/API/SBType.cpp | 88 + lldb/source/API/SBValue.cpp | 19 + lldb/source/Core/Debugger.cpp | 6 +- lldb/source/Core/ThreadedCommunication.cpp | 4 +- .../source/Interpreter/CommandInterpreter.cpp | 6 +- .../Plugins/ExpressionParser/Clang/ASTUtils.h | 4 +- .../ExpressionParser/Clang/ClangASTSource.h | 2 +- .../AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 6 +- .../GDBRemoteCommunicationServerLLGS.cpp | 2 +- .../Python/PythonDataObjects.cpp | 2 +- .../Plugins/SymbolFile/CTF/SymbolFileCTF.cpp | 10 +- .../SymbolFile/DWARF/DWARFASTParserClang.cpp | 1 + .../SymbolFile/DWARF/DWARFCompileUnit.h | 2 +- .../Plugins/SymbolFile/DWARF/DWARFTypeUnit.h | 6 +- .../Plugins/SymbolFile/DWARF/DWARFUnit.cpp | 137 +- .../Plugins/SymbolFile/DWARF/DWARFUnit.h | 68 +- .../TypeSystem/Clang/TypeSystemClang.cpp | 127 +- .../TypeSystem/Clang/TypeSystemClang.h | 8 + lldb/source/Symbol/CompilerDecl.cpp | 9 + lldb/source/Symbol/CompilerType.cpp | 6 + lldb/source/Target/Process.cpp | 6 +- lldb/source/Target/Target.cpp | 6 +- lldb/source/Target/TargetList.cpp | 6 +- lldb/source/Target/Thread.cpp | 6 +- lldb/source/Utility/Broadcaster.cpp | 4 +- .../Makefile | 3 + .../TestClearSBValueNonAddressableBits.py | 59 + .../clear-sbvalue-nonaddressable-bits/main.c | 27 + .../TestDiagnosticReporting.py | 2 +- .../concurrent_vfork/TestConcurrentVFork.py | 16 + .../TestProgressReporting.py | 2 +- .../TestClangModuleBuildProgress.py | 2 +- lldb/test/API/macosx/ctf/Makefile | 2 +- lldb/test/API/macosx/ctf/TestCTF.py | 1 + lldb/test/API/macosx/ctf/test.c | 3 + lldb/test/API/macosx/rosetta/TestRosetta.py | 2 +- lldb/test/API/python_api/type/TestTypeList.py | 41 +- lldb/test/API/python_api/type/main.cpp | 3 + .../tools/lldb-dap/console/TestDAP_console.py | 58 + .../API/tools/lldb-dap/stepInTargets/Makefile | 6 + .../stepInTargets/TestDAP_stepInTargets.py | 68 + .../API/tools/lldb-dap/stepInTargets/main.cpp | 11 + .../DWARF/x86/find-basic-function.cpp | 5 + .../DWARF/x86/find-basic-variable.cpp | 5 + .../Unwind/eh-frame-dwarf-unwind-abort.test | 8 +- lldb/tools/lldb-dap/DAP.h | 2 + lldb/tools/lldb-dap/lldb-dap.cpp | 155 +- lldb/unittests/Host/HostTest.cpp | 21 + lldb/unittests/Host/linux/HostTest.cpp | 16 +- .../cmake/modules/llvm-driver-template.cpp.in | 2 +- ...arfExtensionsForHeterogeneousDebugging.rst | 2 +- llvm/docs/CommandGuide/llvm-objcopy.rst | 6 +- llvm/docs/ConvergenceAndUniformity.rst | 122 +- llvm/docs/ConvergentOperations.rst | 3 +- llvm/docs/GettingInvolved.rst | 3 +- llvm/docs/GlobalISel/IRTranslator.rst | 35 +- llvm/docs/GlobalISel/MIRPatterns.rst | 37 + llvm/docs/LangRef.rst | 90 +- .../docs/MemoryModelRelaxationAnnotations.rst | 481 +++ llvm/docs/Reference.rst | 4 + llvm/docs/ReleaseNotes.rst | 13 +- llvm/docs/Security.rst | 2 +- llvm/docs/WritingAnLLVMBackend.rst | 2 + .../RemoteJITUtils.cpp | 4 +- .../SpeculativeJIT/SpeculativeJIT.cpp | 12 +- llvm/include/llvm-c/DebugInfo.h | 13 + llvm/include/llvm/ADT/StringRef.h | 12 +- .../llvm/Analysis/InstructionSimplify.h | 2 + llvm/include/llvm/Analysis/Loads.h | 17 +- llvm/include/llvm/Analysis/SimplifyQuery.h | 10 +- .../llvm/Analysis/TargetTransformInfo.h | 2 +- llvm/include/llvm/Analysis/ValueTracking.h | 7 +- llvm/include/llvm/Analysis/VectorUtils.h | 2 +- llvm/include/llvm/BinaryFormat/Dwarf.def | 101 +- llvm/include/llvm/BinaryFormat/Dwarf.h | 314 ++ llvm/include/llvm/CodeGen/BasicTTIImpl.h | 6 +- .../llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 + .../CodeGen/GlobalISel/GIMatchTableExecutor.h | 20 +- .../GlobalISel/GIMatchTableExecutorImpl.h | 68 +- .../llvm/CodeGen/GlobalISel/IRTranslator.h | 4 +- .../GlobalISel/LegalizationArtifactCombiner.h | 3 +- .../CodeGen/GlobalISel/MachineIRBuilder.h | 9 + llvm/include/llvm/CodeGen/GlobalISel/Utils.h | 26 + llvm/include/llvm/CodeGen/ISDOpcodes.h | 1 + llvm/include/llvm/CodeGen/MachineFrameInfo.h | 7 + llvm/include/llvm/CodeGen/MachineFunction.h | 3 +- llvm/include/llvm/CodeGen/MachineInstr.h | 115 +- .../llvm/CodeGen/MachineInstrBuilder.h | 45 +- llvm/include/llvm/CodeGen/SelectionDAG.h | 25 + llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 88 +- llvm/include/llvm/CodeGen/TargetInstrInfo.h | 10 + llvm/include/llvm/CodeGen/TargetLowering.h | 7 +- llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 2 +- llvm/include/llvm/ExecutionEngine/Orc/Core.h | 14 +- llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h | 25 +- .../llvm/ExecutionEngine/Orc/TaskDispatch.h | 8 + llvm/include/llvm/Frontend/OpenMP/OMP.h | 10 + .../include/llvm/Frontend/OpenMP/OMPKinds.def | 3 - llvm/include/llvm/IR/Attributes.h | 5 + llvm/include/llvm/IR/EHPersonalities.h | 3 +- llvm/include/llvm/IR/FixedMetadataKinds.def | 1 + llvm/include/llvm/IR/Function.h | 4 + .../llvm/IR/GenericConvergenceVerifierImpl.h | 2 +- llvm/include/llvm/IR/InstrTypes.h | 5 + llvm/include/llvm/IR/IntrinsicInst.h | 19 +- llvm/include/llvm/IR/Intrinsics.td | 37 +- llvm/include/llvm/IR/IntrinsicsAArch64.td | 10 +- llvm/include/llvm/IR/IntrinsicsNVVM.td | 2 + .../IR/MemoryModelRelaxationAnnotations.h | 132 + llvm/include/llvm/IR/PatternMatch.h | 27 +- llvm/include/llvm/MC/MCELFStreamer.h | 2 +- llvm/include/llvm/MC/TargetRegistry.h | 73 +- llvm/include/llvm/Object/ELFObjectFile.h | 13 +- .../llvm/ProfileData/InstrProfWriter.h | 7 +- llvm/include/llvm/ProfileData/MemProf.h | 135 +- llvm/include/llvm/ProfileData/MemProfReader.h | 14 +- llvm/include/llvm/Support/RISCVISAUtils.h | 49 + llvm/include/llvm/Support/YAMLTraits.h | 21 +- .../include/llvm/Target/GlobalISel/Combine.td | 33 +- .../include/llvm/Target/TargetSelectionDAG.td | 1 + .../llvm/TargetParser/AArch64TargetParser.h | 25 +- llvm/include/llvm/TargetParser/CMakeLists.txt | 9 + .../{Support => TargetParser}/RISCVISAInfo.h | 31 +- .../Transforms/InstCombine/InstCombiner.h | 7 +- llvm/include/llvm/Transforms/Scalar/GVN.h | 111 +- .../llvm/Transforms/Scalar/JumpThreading.h | 10 +- .../llvm/Transforms/Utils/GlobalStatus.h | 6 +- llvm/include/llvm/Transforms/Utils/Local.h | 17 + .../Transforms/Utils/MemoryTaggingSupport.h | 2 + .../llvm/Transforms/Vectorize/SLPVectorizer.h | 13 +- llvm/lib/Analysis/BasicAliasAnalysis.cpp | 1 + llvm/lib/Analysis/InstructionSimplify.cpp | 14 +- llvm/lib/Analysis/Loads.cpp | 72 +- llvm/lib/Analysis/LoopAccessAnalysis.cpp | 137 +- llvm/lib/Analysis/ValueTracking.cpp | 39 +- llvm/lib/Analysis/VectorUtils.cpp | 9 +- llvm/lib/BinaryFormat/Dwarf.cpp | 10 + llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp | 9 +- .../CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 21 + llvm/lib/CodeGen/AtomicExpandPass.cpp | 24 +- llvm/lib/CodeGen/CalcSpillWeights.cpp | 3 +- llvm/lib/CodeGen/CodeGenCommonISel.cpp | 3 +- llvm/lib/CodeGen/CodeGenPrepare.cpp | 6 +- .../lib/CodeGen/ComplexDeinterleavingPass.cpp | 30 +- llvm/lib/CodeGen/EarlyIfConversion.cpp | 4 +- .../CodeGen/FixupStatepointCallerSaved.cpp | 2 +- .../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 13 +- .../GlobalISel/CombinerHelperVectorOps.cpp | 25 +- .../lib/CodeGen/GlobalISel/GISelKnownBits.cpp | 14 + llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 13 +- .../CodeGen/GlobalISel/LegalizerHelper.cpp | 2 + .../CodeGen/GlobalISel/MachineIRBuilder.cpp | 4 +- llvm/lib/CodeGen/GlobalISel/RegBankSelect.cpp | 3 +- llvm/lib/CodeGen/GlobalISel/Utils.cpp | 83 + llvm/lib/CodeGen/InlineSpiller.cpp | 2 +- llvm/lib/CodeGen/InterleavedAccessPass.cpp | 4 +- llvm/lib/CodeGen/LiveVariables.cpp | 11 +- llvm/lib/CodeGen/MIRPrinter.cpp | 7 + llvm/lib/CodeGen/MachineCSE.cpp | 2 +- llvm/lib/CodeGen/MachineCombiner.cpp | 20 +- llvm/lib/CodeGen/MachineCopyPropagation.cpp | 2 +- llvm/lib/CodeGen/MachineFunction.cpp | 4 +- llvm/lib/CodeGen/MachineInstr.cpp | 62 +- llvm/lib/CodeGen/MachineLateInstrsCleanup.cpp | 2 +- llvm/lib/CodeGen/MachineSink.cpp | 2 +- llvm/lib/CodeGen/ModuloSchedule.cpp | 9 +- llvm/lib/CodeGen/PHIElimination.cpp | 13 +- llvm/lib/CodeGen/PeepholeOptimizer.cpp | 2 +- llvm/lib/CodeGen/RegisterCoalescer.cpp | 5 +- llvm/lib/CodeGen/RenameIndependentSubregs.cpp | 7 + llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 89 +- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 2 +- .../lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 23 +- .../SelectionDAG/LegalizeFloatTypes.cpp | 39 + llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 4 +- .../SelectionDAG/LegalizeVectorOps.cpp | 8 + .../SelectionDAG/LegalizeVectorTypes.cpp | 8 +- .../SelectionDAG/ScheduleDAGSDNodes.cpp | 9 + .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 164 +- .../SelectionDAG/SelectionDAGBuilder.cpp | 28 +- .../SelectionDAG/SelectionDAGDumper.cpp | 8 + .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 + .../CodeGen/SelectionDAG/TargetLowering.cpp | 58 + llvm/lib/CodeGen/StackSlotColoring.cpp | 3 +- llvm/lib/CodeGen/TargetInstrInfo.cpp | 143 +- .../lib/CodeGen/TwoAddressInstructionPass.cpp | 19 +- llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 41 +- .../Orc/ExecutorProcessControl.cpp | 7 +- llvm/lib/ExecutionEngine/Orc/LLJIT.cpp | 80 +- llvm/lib/ExecutionEngine/Orc/MemoryMapper.cpp | 32 + .../ExecutorSharedMemoryMapperService.cpp | 31 + llvm/lib/ExecutionEngine/Orc/TaskDispatch.cpp | 47 +- llvm/lib/Frontend/OpenMP/OMP.cpp | 102 + llvm/lib/IR/Attributes.cpp | 7 + llvm/lib/IR/AutoUpgrade.cpp | 31 +- llvm/lib/IR/CMakeLists.txt | 1 + llvm/lib/IR/EHPersonalities.cpp | 3 + llvm/lib/IR/Function.cpp | 4 + llvm/lib/IR/IRBuilder.cpp | 6 +- llvm/lib/IR/Instruction.cpp | 1 + llvm/lib/IR/Instructions.cpp | 2 +- llvm/lib/IR/IntrinsicInst.cpp | 11 +- .../IR/MemoryModelRelaxationAnnotations.cpp | 170 + llvm/lib/IR/Verifier.cpp | 27 +- llvm/lib/LTO/LTO.cpp | 4 +- llvm/lib/MC/ELFObjectWriter.cpp | 6 + llvm/lib/MC/MCDXContainerStreamer.cpp | 5 +- llvm/lib/MC/MCELFStreamer.cpp | 5 +- llvm/lib/MC/MCGOFFStreamer.cpp | 5 +- llvm/lib/MC/MCMachOStreamer.cpp | 4 +- llvm/lib/MC/MCObjectStreamer.cpp | 2 + llvm/lib/MC/MCSPIRVStreamer.cpp | 5 +- llvm/lib/MC/MCWasmStreamer.cpp | 5 +- llvm/lib/MC/MCXCOFFStreamer.cpp | 5 +- llvm/lib/MCA/InstrBuilder.cpp | 3 +- llvm/lib/Object/ELFObjectFile.cpp | 2 +- llvm/lib/Object/ModuleSymbolTable.cpp | 14 + llvm/lib/ProfileData/InstrProfReader.cpp | 62 +- llvm/lib/ProfileData/InstrProfWriter.cpp | 27 +- llvm/lib/ProfileData/MemProf.cpp | 51 +- llvm/lib/Support/CMakeLists.txt | 2 +- llvm/lib/Support/RISCVISAUtils.cpp | 88 + llvm/lib/Support/SuffixTree.cpp | 4 +- llvm/lib/Support/YAMLTraits.cpp | 80 +- llvm/lib/Target/AArch64/AArch64.td | 1663 +------- .../AArch64/AArch64Arm64ECCallLowering.cpp | 7 +- .../AArch64/AArch64ConditionOptimizer.cpp | 2 +- .../AArch64/AArch64ConditionalCompares.cpp | 2 +- .../AArch64DeadRegisterDefinitionsPass.cpp | 3 +- llvm/lib/Target/AArch64/AArch64Features.td | 752 ++++ .../Target/AArch64/AArch64FrameLowering.cpp | 2 +- .../Target/AArch64/AArch64ISelLowering.cpp | 374 +- llvm/lib/Target/AArch64/AArch64ISelLowering.h | 8 +- llvm/lib/Target/AArch64/AArch64InstrInfo.cpp | 51 +- llvm/lib/Target/AArch64/AArch64InstrInfo.h | 2 + llvm/lib/Target/AArch64/AArch64InstrInfo.td | 15 + .../lib/Target/AArch64/AArch64MacroFusion.cpp | 4 +- .../Target/AArch64/AArch64PerfectShuffle.h | 43 +- llvm/lib/Target/AArch64/AArch64Processors.td | 976 +++++ .../AArch64RedundantCopyElimination.cpp | 2 +- .../lib/Target/AArch64/AArch64SMEInstrInfo.td | 4 +- .../lib/Target/AArch64/AArch64SVEInstrInfo.td | 53 +- llvm/lib/Target/AArch64/AArch64Subtarget.cpp | 3 +- llvm/lib/Target/AArch64/AArch64Subtarget.h | 58 +- .../AArch64/AArch64TargetTransformInfo.cpp | 21 + .../AArch64/AArch64TargetTransformInfo.h | 2 +- .../AArch64/GISel/AArch64LegalizerInfo.cpp | 23 +- .../GISel/AArch64PostSelectOptimize.cpp | 5 +- .../MCTargetDesc/AArch64ELFObjectWriter.cpp | 93 +- .../MCTargetDesc/AArch64ELFStreamer.cpp | 11 +- .../AArch64/MCTargetDesc/AArch64ELFStreamer.h | 3 +- .../MCTargetDesc/AArch64MCTargetDesc.cpp | 12 +- .../MCTargetDesc/AArch64WinCOFFStreamer.cpp | 2 +- .../MCTargetDesc/AArch64WinCOFFStreamer.h | 2 +- llvm/lib/Target/AArch64/SVEInstrFormats.td | 24 +- llvm/lib/Target/AMDGPU/AMDGPU.td | 11 +- llvm/lib/Target/AMDGPU/AMDGPUISelLowering.cpp | 19 + llvm/lib/Target/AMDGPU/AMDGPUISelLowering.h | 9 + llvm/lib/Target/AMDGPU/AMDGPUInstrInfo.td | 2 + .../lib/Target/AMDGPU/AMDGPULegalizerInfo.cpp | 17 +- .../Target/AMDGPU/AMDGPURegisterBankInfo.cpp | 2 +- .../Target/AMDGPU/AMDGPUTargetTransformInfo.h | 2 +- .../AMDGPU/AsmParser/AMDGPUAsmParser.cpp | 58 +- .../Disassembler/AMDGPUDisassembler.cpp | 8 - llvm/lib/Target/AMDGPU/GCNDPPCombine.cpp | 5 + .../lib/Target/AMDGPU/GCNHazardRecognizer.cpp | 7 +- llvm/lib/Target/AMDGPU/GCNSubtarget.h | 3 + .../AMDGPU/MCTargetDesc/AMDGPUELFStreamer.cpp | 9 +- .../AMDGPU/MCTargetDesc/AMDGPUELFStreamer.h | 3 +- .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp | 10 + .../AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h | 2 + .../MCTargetDesc/AMDGPUMCTargetDesc.cpp | 5 +- llvm/lib/Target/AMDGPU/R600InstrInfo.cpp | 4 +- llvm/lib/Target/AMDGPU/SIFixSGPRCopies.cpp | 5 +- llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 20 +- llvm/lib/Target/AMDGPU/SIInsertWaitcnts.cpp | 6 +- llvm/lib/Target/AMDGPU/SIInstrInfo.cpp | 76 +- llvm/lib/Target/AMDGPU/SIInstrInfo.h | 9 + llvm/lib/Target/AMDGPU/SIInstrInfo.td | 55 +- llvm/lib/Target/AMDGPU/SIInstructions.td | 6 + .../Target/AMDGPU/SIMachineFunctionInfo.cpp | 3 +- .../AMDGPU/SIOptimizeExecMaskingPreRA.cpp | 3 +- llvm/lib/Target/AMDGPU/SIPreEmitPeephole.cpp | 4 +- llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp | 11 +- .../Target/AMDGPU/SIShrinkInstructions.cpp | 2 +- llvm/lib/Target/AMDGPU/SIWholeQuadMode.cpp | 4 +- llvm/lib/Target/AMDGPU/SOPInstructions.td | 2 +- llvm/lib/Target/AMDGPU/VOP3Instructions.td | 46 +- llvm/lib/Target/AMDGPU/VOPInstructions.td | 23 +- llvm/lib/Target/ARM/A15SDOptimizer.cpp | 4 +- llvm/lib/Target/ARM/ARM.td | 1679 +------- llvm/lib/Target/ARM/ARMArchitectures.td | 340 ++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp | 14 +- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 2 +- llvm/lib/Target/ARM/ARMFeatures.td | 753 ++++ llvm/lib/Target/ARM/ARMFrameLowering.cpp | 2 +- llvm/lib/Target/ARM/ARMISelLowering.cpp | 20 +- llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 14 +- llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp | 7 +- llvm/lib/Target/ARM/ARMProcessors.td | 577 +++ llvm/lib/Target/ARM/ARMSubtarget.cpp | 4 - llvm/lib/Target/ARM/ARMSubtarget.h | 82 +- llvm/lib/Target/ARM/ARMTargetTransformInfo.h | 2 +- .../lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 2 +- .../ARM/MCTargetDesc/ARMELFStreamer.cpp | 5 +- .../ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 9 +- .../Target/ARM/MCTargetDesc/ARMMCTargetDesc.h | 1 - .../ARM/MCTargetDesc/ARMWinCOFFStreamer.cpp | 11 +- .../ARM/MVETPAndVPTOptimisationsPass.cpp | 21 +- llvm/lib/Target/ARM/MVEVPTBlockPass.cpp | 3 +- llvm/lib/Target/ARM/Thumb2ITBlockPass.cpp | 3 +- llvm/lib/Target/ARM/Thumb2InstrInfo.cpp | 2 +- llvm/lib/Target/ARM/Thumb2SizeReduction.cpp | 7 +- .../AVR/MCTargetDesc/AVRMCTargetDesc.cpp | 5 +- llvm/lib/Target/BPF/BPFTargetTransformInfo.h | 16 +- llvm/lib/Target/BPF/BTFDebug.cpp | 18 +- llvm/lib/Target/BPF/BTFDebug.h | 4 +- .../BPF/MCTargetDesc/BPFMCTargetDesc.cpp | 14 +- .../CSKY/MCTargetDesc/CSKYMCTargetDesc.cpp | 5 +- .../Target/DirectX/DXILIntrinsicExpansion.cpp | 4 +- llvm/lib/Target/Hexagon/CMakeLists.txt | 1 + .../Target/Hexagon/HexagonCopyHoisting.cpp | 272 ++ .../Target/Hexagon/HexagonCopyToCombine.cpp | 7 +- .../Target/Hexagon/HexagonExpandCondsets.cpp | 9 +- llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 6 +- .../Target/Hexagon/HexagonTargetMachine.cpp | 187 +- .../Hexagon/HexagonTargetTransformInfo.h | 2 +- .../MCTargetDesc/HexagonMCTargetDesc.cpp | 3 +- .../Target/Lanai/LanaiTargetTransformInfo.h | 2 +- .../Lanai/MCTargetDesc/LanaiMCTargetDesc.cpp | 5 +- .../lib/Target/LoongArch/LoongArchSubtarget.h | 38 +- .../MCTargetDesc/LoongArchELFStreamer.cpp | 4 +- .../MCTargetDesc/LoongArchELFStreamer.h | 3 +- .../MCTargetDesc/LoongArchMCTargetDesc.cpp | 5 +- llvm/lib/Target/M68k/M68kExpandPseudo.cpp | 7 + llvm/lib/Target/M68k/M68kISelLowering.cpp | 6 +- llvm/lib/Target/M68k/M68kInstrData.td | 41 +- llvm/lib/Target/M68k/M68kInstrInfo.cpp | 34 + llvm/lib/Target/M68k/M68kInstrInfo.h | 3 + .../Mips/MCTargetDesc/MipsELFStreamer.cpp | 9 +- .../Mips/MCTargetDesc/MipsELFStreamer.h | 3 +- .../lib/Target/Mips/MCTargetDesc/MipsMCNaCl.h | 9 +- .../Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 7 +- .../Mips/MCTargetDesc/MipsNaClELFStreamer.cpp | 11 +- llvm/lib/Target/Mips/Mips32r6InstrInfo.td | 16 + llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 3 +- llvm/lib/Target/Mips/MipsExpandPseudo.cpp | 6 +- llvm/lib/Target/Mips/MipsISelLowering.cpp | 9 + llvm/lib/Target/Mips/MipsInstrInfo.cpp | 4 +- llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.cpp | 6 + llvm/lib/Target/NVPTX/NVPTXISelDAGToDAG.h | 1 + llvm/lib/Target/NVPTX/NVPTXInstrInfo.td | 1 + llvm/lib/Target/NVPTX/NVPTXIntrinsics.td | 25 + .../Target/NVPTX/NVPTXTargetTransformInfo.h | 2 +- .../PowerPC/MCTargetDesc/PPCMCTargetDesc.cpp | 11 +- llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp | 4 +- llvm/lib/Target/PowerPC/PPCCTRLoops.cpp | 9 +- llvm/lib/Target/PowerPC/PPCInstr64Bit.td | 2 +- llvm/lib/Target/PowerPC/PPCInstrInfo.cpp | 17 +- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 4 +- llvm/lib/Target/PowerPC/PPCMIPeephole.cpp | 14 + .../lib/Target/PowerPC/PPCPreEmitPeephole.cpp | 4 +- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 12 +- .../Target/PowerPC/PPCTargetTransformInfo.h | 2 +- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 25 +- .../RISCV/Disassembler/RISCVDisassembler.cpp | 266 +- .../Target/RISCV/MCA/RISCVCustomBehaviour.cpp | 20 - .../RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 1 - .../Target/RISCV/MCTargetDesc/RISCVBaseInfo.h | 2 +- .../RISCV/MCTargetDesc/RISCVELFStreamer.cpp | 4 +- .../RISCV/MCTargetDesc/RISCVELFStreamer.h | 3 +- .../RISCV/MCTargetDesc/RISCVMCTargetDesc.cpp | 14 +- .../RISCV/MCTargetDesc/RISCVMCTargetDesc.h | 16 +- .../MCTargetDesc/RISCVTargetStreamer.cpp | 2 +- llvm/lib/Target/RISCV/RISCV.h | 3 + llvm/lib/Target/RISCV/RISCV.td | 6 + llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp | 2 +- llvm/lib/Target/RISCV/RISCVFeatures.td | 12 +- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 1 - llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h | 9 - llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 220 +- llvm/lib/Target/RISCV/RISCVISelLowering.h | 6 + .../Target/RISCV/RISCVInsertReadWriteCSR.cpp | 5 +- llvm/lib/Target/RISCV/RISCVInsertVSETVLI.cpp | 389 +- .../lib/Target/RISCV/RISCVInsertWriteVXRM.cpp | 6 +- llvm/lib/Target/RISCV/RISCVInstrInfo.cpp | 302 +- llvm/lib/Target/RISCV/RISCVInstrInfo.h | 26 + llvm/lib/Target/RISCV/RISCVInstrInfo.td | 2 + llvm/lib/Target/RISCV/RISCVInstrInfoC.td | 2 +- .../Target/RISCV/RISCVInstrInfoVPseudos.td | 35 +- llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td | 26 +- llvm/lib/Target/RISCV/RISCVInstrInfoZb.td | 61 +- llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td | 2 +- llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp | 2 +- llvm/lib/Target/RISCV/RISCVProfiles.td | 204 + llvm/lib/Target/RISCV/RISCVTargetMachine.cpp | 17 +- .../Target/RISCV/RISCVTargetTransformInfo.h | 2 +- .../SPIRV/MCTargetDesc/SPIRVMCTargetDesc.cpp | 4 +- llvm/lib/Target/SPIRV/SPIRVBuiltins.cpp | 13 +- llvm/lib/Target/SPIRV/SPIRVBuiltins.td | 4 +- llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp | 97 +- llvm/lib/Target/SPIRV/SPIRVISelLowering.cpp | 10 + .../Target/SPIRV/SPIRVInstructionSelector.cpp | 56 +- llvm/lib/Target/SPIRV/SPIRVPreLegalizer.cpp | 55 +- .../lib/Target/SPIRV/SPIRVSymbolicOperands.td | 2 + .../lib/Target/SystemZ/SystemZElimCompare.cpp | 6 +- .../Target/SystemZ/SystemZISelLowering.cpp | 18 +- llvm/lib/Target/SystemZ/SystemZInstrInfo.cpp | 20 +- .../SystemZ/SystemZTargetTransformInfo.h | 2 +- llvm/lib/Target/WebAssembly/CMakeLists.txt | 1 + .../WebAssemblyMCTypeUtilities.cpp | 28 +- llvm/lib/Target/WebAssembly/WebAssembly.h | 2 + llvm/lib/Target/WebAssembly/WebAssembly.td | 3 + .../WebAssemblyCleanCodeAfterTrap.cpp | 80 + .../WebAssemblyDebugValueManager.cpp | 2 +- .../WebAssembly/WebAssemblyISelLowering.cpp | 4 +- .../WebAssembly/WebAssemblyInstrInfo.td | 4 + .../WebAssemblyMachineFunctionInfo.cpp | 6 +- .../WebAssemblyRefTypeMem2Local.cpp | 5 +- .../WebAssembly/WebAssemblyRegStackify.cpp | 11 +- .../WebAssemblyRuntimeLibcallSignatures.cpp | 25 +- .../Target/WebAssembly/WebAssemblySubtarget.h | 2 + .../WebAssembly/WebAssemblyTargetMachine.cpp | 20 +- .../WebAssembly/WebAssemblyTargetMachine.h | 3 + .../WebAssemblyTargetTransformInfo.h | 2 +- .../WebAssembly/WebAssemblyUtilities.cpp | 14 +- .../Target/WebAssembly/WebAssemblyUtilities.h | 10 + .../lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 21 +- .../Target/X86/MCTargetDesc/X86MCTargetDesc.h | 1 - .../X86/MCTargetDesc/X86WinCOFFStreamer.cpp | 2 - llvm/lib/Target/X86/X86CmovConversion.cpp | 8 +- llvm/lib/Target/X86/X86FixupSetCC.cpp | 4 +- llvm/lib/Target/X86/X86FlagsCopyLowering.cpp | 16 +- llvm/lib/Target/X86/X86FloatingPoint.cpp | 28 +- llvm/lib/Target/X86/X86ISelLowering.cpp | 299 +- llvm/lib/Target/X86/X86InstrInfo.cpp | 41 +- llvm/lib/Target/X86/X86LowerTileCopy.cpp | 73 +- llvm/lib/Target/X86/X86MCInstLower.cpp | 3 +- llvm/lib/Target/X86/X86PfmCounters.td | 16 + llvm/lib/Target/X86/X86RegisterInfo.cpp | 9 +- llvm/lib/Target/X86/X86SchedAlderlakeP.td | 6 + .../X86/X86SpeculativeLoadHardening.cpp | 16 +- llvm/lib/Target/X86/X86Subtarget.h | 3 +- .../lib/Target/X86/X86TargetTransformInfo.cpp | 16 +- llvm/lib/Target/X86/X86TargetTransformInfo.h | 2 +- .../Xtensa/AsmParser/XtensaAsmParser.cpp | 131 +- llvm/lib/Target/Xtensa/CMakeLists.txt | 3 + .../Target/Xtensa/MCTargetDesc/CMakeLists.txt | 1 + .../MCTargetDesc/XtensaMCTargetDesc.cpp | 28 +- .../MCTargetDesc/XtensaTargetStreamer.cpp | 119 + .../MCTargetDesc/XtensaTargetStreamer.h | 58 + llvm/lib/Target/Xtensa/Xtensa.td | 6 + llvm/lib/Target/Xtensa/XtensaAsmPrinter.cpp | 148 + llvm/lib/Target/Xtensa/XtensaAsmPrinter.h | 13 + llvm/lib/Target/Xtensa/XtensaCallingConv.td | 24 + .../Target/Xtensa/XtensaConstantPoolValue.cpp | 207 + .../Target/Xtensa/XtensaConstantPoolValue.h | 263 ++ .../lib/Target/Xtensa/XtensaFrameLowering.cpp | 20 + llvm/lib/Target/Xtensa/XtensaFrameLowering.h | 4 + llvm/lib/Target/Xtensa/XtensaISelDAGToDAG.cpp | 52 +- llvm/lib/Target/Xtensa/XtensaISelLowering.cpp | 501 +++ llvm/lib/Target/Xtensa/XtensaISelLowering.h | 44 + llvm/lib/Target/Xtensa/XtensaInstrInfo.cpp | 137 +- llvm/lib/Target/Xtensa/XtensaInstrInfo.h | 29 + llvm/lib/Target/Xtensa/XtensaInstrInfo.td | 55 +- llvm/lib/Target/Xtensa/XtensaOperands.td | 2 +- llvm/lib/Target/Xtensa/XtensaOperators.td | 36 + llvm/lib/Target/Xtensa/XtensaRegisterInfo.cpp | 74 +- llvm/lib/Target/Xtensa/XtensaUtils.cpp | 59 + llvm/lib/Target/Xtensa/XtensaUtils.h | 27 + llvm/lib/TargetParser/CMakeLists.txt | 3 + llvm/lib/TargetParser/Host.cpp | 3 + .../RISCVISAInfo.cpp | 556 +-- llvm/lib/TargetParser/RISCVTargetParser.cpp | 2 +- llvm/lib/Transforms/Coroutines/CoroInstr.h | 4 +- llvm/lib/Transforms/IPO/FunctionAttrs.cpp | 27 +- llvm/lib/Transforms/IPO/GlobalOpt.cpp | 7 + llvm/lib/Transforms/IPO/SCCP.cpp | 27 +- llvm/lib/Transforms/IPO/SampleProfile.cpp | 25 +- .../InstCombine/InstCombineAddSub.cpp | 74 +- .../InstCombine/InstCombineAndOrXor.cpp | 24 +- .../InstCombine/InstCombineCalls.cpp | 33 +- .../InstCombine/InstCombineCasts.cpp | 6 +- .../InstCombine/InstCombineCompares.cpp | 30 +- .../InstCombine/InstCombineInternal.h | 7 +- .../InstCombine/InstCombineMulDivRem.cpp | 2 +- .../InstCombine/InstCombineNegator.cpp | 3 +- .../InstCombine/InstCombineSelect.cpp | 12 +- .../InstCombine/InstCombineShifts.cpp | 16 - .../InstCombine/InstructionCombining.cpp | 101 +- .../Instrumentation/HWAddressSanitizer.cpp | 63 +- .../Instrumentation/MemorySanitizer.cpp | 56 +- .../Instrumentation/PGOInstrumentation.cpp | 1 + .../Transforms/Scalar/DFAJumpThreading.cpp | 44 +- llvm/lib/Transforms/Scalar/GVN.cpp | 167 +- .../Scalar/InductiveRangeCheckElimination.cpp | 3 + llvm/lib/Transforms/Scalar/JumpThreading.cpp | 41 +- .../Transforms/Scalar/LoopLoadElimination.cpp | 4 +- .../lib/Transforms/Scalar/MemCpyOptimizer.cpp | 119 +- llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 10 +- llvm/lib/Transforms/Utils/CloneFunction.cpp | 3 + .../Utils/EntryExitInstrumenter.cpp | 3 +- llvm/lib/Transforms/Utils/GlobalStatus.cpp | 11 +- llvm/lib/Transforms/Utils/Local.cpp | 67 +- llvm/lib/Transforms/Utils/LoopUtils.cpp | 6 +- .../Transforms/Utils/MemoryTaggingSupport.cpp | 33 + llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 22 +- .../Transforms/Vectorize/LoopVectorize.cpp | 53 +- .../Transforms/Vectorize/SLPVectorizer.cpp | 703 +++- llvm/lib/Transforms/Vectorize/VPlan.h | 7 +- .../Transforms/Vectorize/VPlanAnalysis.cpp | 7 + .../Transforms/Vectorize/VPlanPatternMatch.h | 17 +- .../Transforms/Vectorize/VPlanTransforms.cpp | 44 +- .../Transforms/Vectorize/VectorCombine.cpp | 98 +- .../getIntrinsicInstrCost-vector-reverse.ll | 96 +- .../test/Analysis/CostModel/AArch64/splice.ll | 172 +- .../CostModel/AArch64/sve-intrinsics.ll | 688 ++-- .../test/Analysis/CostModel/RISCV/arith-fp.ll | 62 +- .../Analysis/CostModel/RISCV/arith-int.ll | 52 +- .../Analysis/CostModel/RISCV/rvv-shuffle.ll | 250 +- llvm/test/Analysis/CostModel/RISCV/splice.ll | 392 +- .../Analysis/CostModel/X86/load-broadcast.ll | 556 +++ ...es-safe-dep-due-to-backedge-taken-count.ll | 154 + .../non-constant-strides-forward.ll | 10 +- .../Analysis/ValueTracking/known-non-zero.ll | 77 +- ...or-interleave2-deinterleave2-intrinsics.ll | 46 + .../upgrade-vector-reverse-intrinsic.ll | 24 + .../upgrade-vector-splice-intrinsic.ll | 24 + .../GlobalISel/combine-insert-vec-elt.mir | 110 + .../AArch64/GlobalISel/combine-udiv.ll | 26 + .../irtranslator-vector-deinterleave2.ll | 4 +- .../irtranslator-vector-interleave2.ll | 4 +- .../AArch64/GlobalISel/legalize-bitcast.mir | 50 + .../legalize-extract-vector-elt.mir | 15 +- .../AArch64/GlobalISel/legalize-fp-arith.mir | 7 +- .../AArch64/GlobalISel/legalize-freeze.mir | 92 + .../GlobalISel/legalize-insert-vector-elt.mir | 17 +- .../AArch64/GlobalISel/legalize-itofp.mir | 14 +- .../GlobalISel/legalize-load-store.mir | 24 +- .../AArch64/GlobalISel/legalize-min-max.mir | 84 +- .../AArch64/GlobalISel/legalize-phi.mir | 28 +- .../AArch64/GlobalISel/legalize-select.mir | 66 +- .../AArch64/GlobalISel/legalize-shift.mir | 10 +- .../GlobalISel/legalize-shuffle-vector.mir | 7 +- .../GlobalISel/legalizer-info-validation.mir | 12 +- llvm/test/CodeGen/AArch64/arm64-uzp.ll | 30 +- llvm/test/CodeGen/AArch64/arm64-zip.ll | 18 +- .../CodeGen/AArch64/arm64ec-entry-thunks.ll | 6 +- .../CodeGen/AArch64/arm64ec-exit-thunks.ll | 10 +- llvm/test/CodeGen/AArch64/combine-mul.ll | 7 +- ...interleaving-add-mull-scalable-contract.ll | 52 +- ...x-deinterleaving-add-mull-scalable-fast.ll | 52 +- ...complex-deinterleaving-f16-add-scalable.ll | 40 +- .../AArch64/complex-deinterleaving-f16-add.ll | 30 +- ...complex-deinterleaving-f16-mul-scalable.ll | 40 +- ...complex-deinterleaving-f32-add-scalable.ll | 30 +- ...complex-deinterleaving-f32-mul-scalable.ll | 30 +- ...complex-deinterleaving-f64-add-scalable.ll | 30 +- ...complex-deinterleaving-f64-mul-scalable.ll | 30 +- ...complex-deinterleaving-i16-add-scalable.ll | 40 +- ...complex-deinterleaving-i16-mul-scalable.ll | 40 +- ...complex-deinterleaving-i32-add-scalable.ll | 30 +- ...complex-deinterleaving-i32-mul-scalable.ll | 30 +- ...complex-deinterleaving-i64-add-scalable.ll | 30 +- ...complex-deinterleaving-i64-mul-scalable.ll | 36 +- .../complex-deinterleaving-i8-add-scalable.ll | 30 +- ...rleaving-reductions-predicated-scalable.ll | 26 +- ...plex-deinterleaving-reductions-scalable.ll | 44 +- .../complex-deinterleaving-splat-scalable.ll | 16 +- llvm/test/CodeGen/AArch64/concatbinop.ll | 201 + .../AArch64/fixed-vector-deinterleave.ll | 40 +- .../AArch64/fixed-vector-interleave.ll | 40 +- llvm/test/CodeGen/AArch64/fpmode.ll | 43 +- .../AArch64/machine-combiner-subadd2.mir | 27 + llvm/test/CodeGen/AArch64/mul_pow2.ll | 64 +- .../named-vector-shuffle-reverse-neon.ll | 52 +- .../named-vector-shuffle-reverse-sve.ll | 84 +- .../AArch64/named-vector-shuffles-neon.ll | 30 +- .../AArch64/named-vector-shuffles-sve.ll | 164 +- ...sve-streaming-mode-fixed-length-bitcast.ll | 7 +- ...ng-mode-fixed-length-extract-vector-elt.ll | 2 - ...streaming-mode-fixed-length-fp-compares.ll | 8 +- .../sve-streaming-mode-fixed-length-fp-fma.ll | 3 - ...e-streaming-mode-fixed-length-fp-minmax.ll | 8 - ...e-streaming-mode-fixed-length-fp-reduce.ll | 10 - ...streaming-mode-fixed-length-fp-rounding.ll | 7 - ...e-streaming-mode-fixed-length-fp-select.ll | 11 +- ...e-streaming-mode-fixed-length-fp-to-int.ll | 2 - ...-streaming-mode-fixed-length-fp-vselect.ll | 11 +- ...-streaming-mode-fixed-length-ld2-alloca.ll | 4 +- .../sve-streaming-mode-fixed-length-loads.ll | 11 +- ...eaming-mode-fixed-length-optimize-ptrue.ll | 14 +- ...e-streaming-mode-fixed-length-subvector.ll | 9 +- .../AArch64/sve-vector-deinterleave.ll | 76 +- .../CodeGen/AArch64/sve-vector-interleave.ll | 76 +- llvm/test/CodeGen/AArch64/sve-vl-arith.ll | 26 +- llvm/test/CodeGen/AArch64/sve2-bsl.ll | 52 + .../AArch64/sve2-intrinsics-while-reversed.ll | 741 ++++ llvm/test/CodeGen/AArch64/vecreduce-add.ll | 14 +- .../vscale-and-sve-cnt-demandedbits.ll | 10 +- .../AMDGPU/GlobalISel/legalize-trap-gfx11.mir | 49 + .../GlobalISel/llvm.amdgcn.intersect_ray.ll | 291 +- llvm/test/CodeGen/AMDGPU/GlobalISel/mmra.ll | 34 + llvm/test/CodeGen/AMDGPU/amdpal-callable.ll | 4 +- llvm/test/CodeGen/AMDGPU/amdpal-cs.ll | 4 +- llvm/test/CodeGen/AMDGPU/amdpal-es.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-gs.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-hs.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-ls.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-cs.ll | 2 +- .../CodeGen/AMDGPU/amdpal-msgpack-default.ll | 44 +- .../CodeGen/AMDGPU/amdpal-msgpack-denormal.ll | 44 +- .../AMDGPU/amdpal-msgpack-dx10-clamp.ll | 44 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-es.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-gs.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-hs.ll | 2 +- .../CodeGen/AMDGPU/amdpal-msgpack-ieee.ll | 58 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-ls.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-ps.ll | 8 +- .../CodeGen/AMDGPU/amdpal-msgpack-psenable.ll | 4 +- llvm/test/CodeGen/AMDGPU/amdpal-msgpack-vs.ll | 2 +- llvm/test/CodeGen/AMDGPU/amdpal-psenable.ll | 8 +- .../CodeGen/AMDGPU/amdpal-usersgpr-init.ll | 4 +- llvm/test/CodeGen/AMDGPU/amdpal-vs.ll | 2 +- llvm/test/CodeGen/AMDGPU/atomic_load_local.ll | 54 + .../test/CodeGen/AMDGPU/atomic_store_local.ll | 53 + llvm/test/CodeGen/AMDGPU/div_i128.ll | 96 +- llvm/test/CodeGen/AMDGPU/extra-lds-size.ll | 4 +- llvm/test/CodeGen/AMDGPU/flat_atomics.ll | 273 ++ llvm/test/CodeGen/AMDGPU/flat_atomics_i64.ll | 4 +- .../CodeGen/AMDGPU/fp_trunc_store_bf16.ll | 426 ++ llvm/test/CodeGen/AMDGPU/global_atomics.ll | 279 ++ .../test/CodeGen/AMDGPU/global_atomics_i64.ll | 4 +- .../CodeGen/AMDGPU/hard-clauses-img-gfx10.mir | 34 + .../CodeGen/AMDGPU/hard-clauses-img-gfx11.mir | 40 + .../CodeGen/AMDGPU/hard-clauses-img-gfx12.mir | 40 + llvm/test/CodeGen/AMDGPU/hard-clauses.mir | 235 +- ...rval-bug-in-rename-independent-subregs.mir | 208 + .../CodeGen/AMDGPU/llvm.amdgcn.cvt.fp8.dpp.ll | 8 +- .../CodeGen/AMDGPU/llvm.amdgcn.cvt.fp8.ll | 12 +- .../AMDGPU/llvm.amdgcn.s.wait.event.ll | 10 +- .../test/CodeGen/AMDGPU/llvm.fptrunc.round.ll | 453 ++- .../lower-work-group-id-intrinsics-pal.ll | 63 +- llvm/test/CodeGen/AMDGPU/mad_64_32.ll | 1 + llvm/test/CodeGen/AMDGPU/mmra.ll | 189 + .../AMDGPU/mode-register-fpconstrain.ll | 43 + llvm/test/CodeGen/AMDGPU/pal-userdata-regs.ll | 12 +- llvm/test/CodeGen/AMDGPU/rem_i128.ll | 475 +-- llvm/test/CodeGen/AMDGPU/trap-abis.ll | 137 + .../test/CodeGen/AMDGPU/wave_dispatch_regs.ll | 8 +- .../CodeGen/ARM/minnum-maxnum-intrinsics.ll | 28 +- .../CodeGen/BPF/CORE/offset-reloc-basic.ll | 4 +- llvm/test/CodeGen/Hexagon/arg-copy-elison.ll | 39 + .../CodeGen/Hexagon/hexagon-copy-hoisting.mir | 53 + .../lasx/ir-instruction/insertelement.ll | 42 +- .../lsx/ir-instruction/insertelement.ll | 42 +- llvm/test/CodeGen/LoongArch/sextw-removal.ll | 921 +++++ .../CodeGen/M68k/Arith/add-with-overflow.ll | 2 +- llvm/test/CodeGen/M68k/Arith/add.ll | 4 +- llvm/test/CodeGen/M68k/Arith/bitwise.ll | 6 +- .../CodeGen/M68k/Arith/divide-by-constant.ll | 14 +- llvm/test/CodeGen/M68k/Arith/imul.ll | 16 +- .../CodeGen/M68k/Arith/smul-with-overflow.ll | 12 +- .../CodeGen/M68k/Arith/sub-with-overflow.ll | 10 +- llvm/test/CodeGen/M68k/Arith/sub.ll | 2 +- .../CodeGen/M68k/Arith/umul-with-overflow.ll | 6 +- llvm/test/CodeGen/M68k/CConv/c-call.ll | 6 +- llvm/test/CodeGen/M68k/CConv/fastcc-call.ll | 12 +- .../CodeModel/medium-pie-global-access.ll | 4 +- .../M68k/CodeModel/small-pie-global-access.ll | 4 +- llvm/test/CodeGen/M68k/Control/cmp.ll | 26 +- llvm/test/CodeGen/M68k/Control/long-setcc.ll | 4 +- llvm/test/CodeGen/M68k/Control/setcc.ll | 6 +- llvm/test/CodeGen/M68k/PR57660.ll | 2 +- llvm/test/CodeGen/M68k/gcc_except_table.ll | 2 +- llvm/test/CodeGen/M68k/link-unlnk.ll | 4 +- llvm/test/CodeGen/Mips/atomic-min-max.ll | 12 +- llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll | 69 + llvm/test/CodeGen/Mips/msa/f16-llvm-ir.ll | 487 ++- llvm/test/CodeGen/NVPTX/rsqrt-opt.ll | 75 + llvm/test/CodeGen/NVPTX/rsqrt.ll | 35 + .../CodeGen/PowerPC/fminimum-fmaximum-f128.ll | 97 + .../test/CodeGen/PowerPC/fminimum-fmaximum.ll | 847 ++++ llvm/test/CodeGen/PowerPC/legalize-vaarg.ll | 17 - .../CodeGen/PowerPC/peephole-counter-XToI.mir | 85 + .../PowerPC/peephole-counter-perOp.mir | 74 + llvm/test/CodeGen/RISCV/O0-pipeline.ll | 4 + llvm/test/CodeGen/RISCV/O3-pipeline.ll | 1 + llvm/test/CodeGen/RISCV/addimm-mulimm.ll | 205 +- llvm/test/CodeGen/RISCV/alu64.ll | 2 +- llvm/test/CodeGen/RISCV/atomic-rmw.ll | 108 +- llvm/test/CodeGen/RISCV/atomic-signext.ll | 8 +- .../CodeGen/RISCV/atomicrmw-uinc-udec-wrap.ll | 16 +- llvm/test/CodeGen/RISCV/attributes.ll | 37 +- llvm/test/CodeGen/RISCV/bfloat-convert.ll | 108 +- llvm/test/CodeGen/RISCV/bitreverse-shift.ll | 2 +- llvm/test/CodeGen/RISCV/double-convert.ll | 111 +- .../CodeGen/RISCV/double-round-conv-sat.ll | 138 +- llvm/test/CodeGen/RISCV/fixups-diff.ll | 2 +- llvm/test/CodeGen/RISCV/float-convert.ll | 158 +- .../CodeGen/RISCV/float-round-conv-sat.ll | 288 +- llvm/test/CodeGen/RISCV/forced-atomics.ll | 4 +- llvm/test/CodeGen/RISCV/fpclamptosat.ll | 4 +- llvm/test/CodeGen/RISCV/half-convert.ll | 268 +- .../test/CodeGen/RISCV/half-round-conv-sat.ll | 624 ++- llvm/test/CodeGen/RISCV/iabs.ll | 4 +- llvm/test/CodeGen/RISCV/pr84653_pr85190.ll | 95 + llvm/test/CodeGen/RISCV/pr89833.ll | 16 + llvm/test/CodeGen/RISCV/rv32zba.ll | 8 +- .../CodeGen/RISCV/rv64-legal-i32/rv64zba.ll | 14 +- .../RISCV/rv64-legal-i32/rv64zbb-zbkb.ll | 58 +- .../CodeGen/RISCV/rv64-legal-i32/xaluo.ll | 24 +- .../test/CodeGen/RISCV/rv64i-demanded-bits.ll | 14 + llvm/test/CodeGen/RISCV/rv64xtheadba.ll | 177 + llvm/test/CodeGen/RISCV/rv64zba.ll | 206 +- llvm/test/CodeGen/RISCV/rvv/commutable.ll | 824 ++++ .../rvv/fixed-vectors-deinterleave-load.ll | 46 +- .../RISCV/rvv/fixed-vectors-fp-buildvec.ll | 4 +- .../RISCV/rvv/fixed-vectors-fp-interleave.ll | 4 +- .../RISCV/rvv/fixed-vectors-fp2i-sat.ll | 8 +- .../RISCV/rvv/fixed-vectors-int-interleave.ll | 8 +- .../RISCV/rvv/fixed-vectors-int-shuffles.ll | 32 +- .../rvv/fixed-vectors-interleave-store.ll | 42 +- .../rvv/fixed-vectors-interleaved-access.ll | 637 +-- .../RISCV/rvv/fixed-vectors-mask-buildvec.ll | 12 +- .../RISCV/rvv/fixed-vectors-mask-splat.ll | 6 +- .../RISCV/rvv/fixed-vectors-masked-gather.ll | 28 +- .../rvv/fixed-vectors-reduction-formation.ll | 56 +- .../rvv/fixed-vectors-reduction-int-vp.ll | 104 +- ...fixed-vectors-shuffle-reverse-bitrotate.ll | 4 +- .../rvv/fixed-vectors-shuffle-reverse.ll | 188 +- .../CodeGen/RISCV/rvv/fpclamptosat_vec.ll | 521 +-- .../RISCV/rvv/named-vector-shuffle-reverse.ll | 184 +- .../test/CodeGen/RISCV/rvv/shuffle-reverse.ll | 6 +- .../RISCV/rvv/vector-deinterleave-fixed.ll | 44 +- .../RISCV/rvv/vector-deinterleave-load.ll | 54 +- .../CodeGen/RISCV/rvv/vector-deinterleave.ll | 76 +- .../RISCV/rvv/vector-interleave-fixed.ll | 40 +- .../RISCV/rvv/vector-interleave-store.ll | 62 +- .../CodeGen/RISCV/rvv/vector-interleave.ll | 256 +- .../RISCV/rvv/vector-reassociations.ll | 253 ++ llvm/test/CodeGen/RISCV/rvv/vector-splice.ll | 412 +- llvm/test/CodeGen/RISCV/rvv/vmfeq.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmfge.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmfgt.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmfle.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmflt.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmfne.ll | 72 +- llvm/test/CodeGen/RISCV/rvv/vmseq.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsge.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsgeu.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsgt.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsgtu.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsle.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsleu.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmslt.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsltu.ll | 106 +- llvm/test/CodeGen/RISCV/rvv/vmsne.ll | 106 +- .../CodeGen/RISCV/rvv/vreductions-int-vp.ll | 230 +- .../RISCV/rvv/vsetvli-insert-crossbb.ll | 120 +- .../RISCV/rvv/vsetvli-insert-crossbb.mir | 25 +- .../test/CodeGen/RISCV/rvv/vsetvli-insert.mir | 36 +- llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll | 1 - llvm/test/CodeGen/RISCV/rvv/zvlsseg-spill.mir | 2 +- llvm/test/CodeGen/RISCV/select.ll | 110 + llvm/test/CodeGen/RISCV/xaluo.ll | 67 +- .../SPIRV/pointers/argument-ptr-to-struct.ll | 37 + .../CodeGen/SPIRV/pointers/global-ptrtoint.ll | 28 + .../SPIRV/pointers/variables-storage-class.ll | 19 + llvm/test/CodeGen/SPIRV/printf.ll | 40 + .../CodeGen/SPIRV/transcoding/memcpy-zext.ll | 20 +- .../SPIRV/transcoding/spirv-event-null.ll | 33 + llvm/test/CodeGen/SPIRV/types/or-i1.ll | 17 + llvm/test/CodeGen/SystemZ/atomic-load-08.ll | 48 +- llvm/test/CodeGen/SystemZ/atomic-store-08.ll | 51 +- .../test/CodeGen/SystemZ/atomicrmw-xchg-07.ll | 42 + llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll | 12 + .../lower-em-ehsjlj-multi-return.ll | 4 +- .../multivalue-dont-move-def-past-use.mir | 2 +- .../WebAssembly/multivalue-stackify.ll | 2 +- llvm/test/CodeGen/WebAssembly/multivalue.ll | 10 +- .../CodeGen/WebAssembly/multivalue_libcall.ll | 2 +- .../CodeGen/WebAssembly/ref-type-mem2local.ll | 36 +- llvm/test/CodeGen/WebAssembly/unreachable.ll | 11 +- .../CodeGen/X86/AMX/amx-lower-tile-copy.ll | 10 - llvm/test/CodeGen/X86/abdu-vector-128.ll | 54 +- .../CodeGen/X86/apx/kmov-postrapseudos.ll | 10 +- llvm/test/CodeGen/X86/avgceils.ll | 238 +- llvm/test/CodeGen/X86/avgceilu.ll | 138 +- llvm/test/CodeGen/X86/avgfloors.ll | 238 +- llvm/test/CodeGen/X86/avgflooru.ll | 138 +- .../CodeGen/X86/avx512-broadcast-arith.ll | 10 +- llvm/test/CodeGen/X86/avx512bwvl-arith.ll | 35 +- llvm/test/CodeGen/X86/cmp.ll | 570 +-- llvm/test/CodeGen/X86/combine-mul.ll | 8 +- llvm/test/CodeGen/X86/combine-or-shuffle.ll | 862 ++++ llvm/test/CodeGen/X86/combine-or.ll | 606 +-- .../X86/div-rem-pair-recomposition-signed.ll | 377 +- llvm/test/CodeGen/X86/fold-masked-merge.ll | 4 +- llvm/test/CodeGen/X86/freeze-binary.ll | 50 +- llvm/test/CodeGen/X86/freeze-combine.ll | 16 +- llvm/test/CodeGen/X86/freeze-vector.ll | 20 + llvm/test/CodeGen/X86/gfni-funnel-shifts.ll | 4 +- llvm/test/CodeGen/X86/gfni-rotates.ll | 14 +- llvm/test/CodeGen/X86/known-never-zero.ll | 30 +- llvm/test/CodeGen/X86/memcmp-minsize-x32.ll | 4 +- llvm/test/CodeGen/X86/memcmp-minsize.ll | 6 +- llvm/test/CodeGen/X86/memcmp-optsize-x32.ll | 4 +- llvm/test/CodeGen/X86/memcmp-optsize.ll | 6 +- llvm/test/CodeGen/X86/memcmp-pgso-x32.ll | 4 +- llvm/test/CodeGen/X86/memcmp-pgso.ll | 6 +- llvm/test/CodeGen/X86/midpoint-int-vec-128.ll | 94 +- llvm/test/CodeGen/X86/midpoint-int-vec-256.ll | 32 +- llvm/test/CodeGen/X86/midpoint-int-vec-512.ll | 80 +- .../X86/named-vector-shuffle-reverse.ll | 38 +- llvm/test/CodeGen/X86/pr34592.ll | 117 +- llvm/test/CodeGen/X86/pr38539.ll | 202 +- llvm/test/CodeGen/X86/pr62286.ll | 31 +- .../CodeGen/X86/scheduler-backtracking.ll | 2 +- llvm/test/CodeGen/X86/sdiv_fix_sat.ll | 250 +- .../test/CodeGen/X86/setcc-non-simple-type.ll | 78 +- llvm/test/CodeGen/X86/shift-combine.ll | 35 + llvm/test/CodeGen/X86/subreg-to-reg-1.ll | 9 +- llvm/test/CodeGen/X86/subreg-to-reg-3.ll | 8 +- llvm/test/CodeGen/X86/subreg-to-reg-6.ll | 22 +- .../subvectorwise-store-of-vector-splat.ll | 56 +- llvm/test/CodeGen/X86/vec_saddo.ll | 14 +- llvm/test/CodeGen/X86/vec_ssubo.ll | 14 +- llvm/test/CodeGen/X86/vec_uaddo.ll | 14 +- llvm/test/CodeGen/X86/vec_usubo.ll | 14 +- llvm/test/CodeGen/X86/vector-bo-select.ll | 10 +- llvm/test/CodeGen/X86/vector-fshr-128.ll | 86 +- llvm/test/CodeGen/X86/vector-fshr-256.ll | 28 +- llvm/test/CodeGen/X86/vector-fshr-sub128.ll | 12 +- llvm/test/CodeGen/X86/vector-shift-shl-128.ll | 12 +- llvm/test/CodeGen/Xtensa/call.ll | 49 + llvm/test/CodeGen/Xtensa/calling-conv.ll | 78 + llvm/test/CodeGen/Xtensa/constantpool.ll | 28 + llvm/test/CodeGen/Xtensa/stack-access.ll | 35 + .../LoongArch/dwarf-loongarch-relocs.ll | 18 +- .../DebugInfo/RISCV/dwarf-riscv-relocs.ll | 12 +- .../test/DebugInfo/RISCV/relax-debug-frame.ll | 10 +- ...name-symbol.s => riscv-temporary-symbol.s} | 5 +- .../X86/call-origin-linkage-names.ll | 96 + .../X86/invalid-cu-abbrev-contribution-dwp.s | 58 + .../X86/invalid-cu-abbrev-offset-dwp.s | 58 + .../DebugInfo/X86/invalid-cu-length-dwp.s | 4 +- .../JITLink/RISCV/anonymous_symbol.s | 2 +- .../HWAddressSanitizer/basic.ll | 22 +- .../HWAddressSanitizer/fixed-shadow.ll | 229 ++ .../HWAddressSanitizer/prologue.ll | 4 +- .../Coro/coro-split-musttail.ll | 63 - .../Coro/coro-split-musttail1.ll | 97 - .../Coro/coro-split-musttail10.ll | 55 - .../Coro/coro-split-musttail11.ll | 55 - .../Coro/coro-split-musttail12.ll | 85 - .../Coro/coro-split-musttail13.ll | 76 - .../Coro/coro-split-musttail2.ll | 68 - .../Coro/coro-split-musttail3.ll | 91 - .../Coro/coro-split-musttail4.ll | 66 - .../Coro/coro-split-musttail5.ll | 63 - .../Coro/coro-split-musttail6.ll | 112 - .../Coro/coro-split-musttail7.ll | 115 - .../MemorySanitizer/X86/mmx-intrinsics.ll | 3617 +++++++++++++++++ .../Instrumentation/MemorySanitizer/vscale.ll | 188 + llvm/test/LTO/X86/codemodel-2.ll | 2 +- llvm/test/LTO/X86/codemodel-3.ll | 3 +- llvm/test/LTO/X86/largedatathreshold-1.ll | 2 +- llvm/test/LTO/X86/largedatathreshold-2.ll | 2 +- llvm/test/LTO/X86/largedatathreshold-3.ll | 3 +- .../test/MC/AArch64/SME2p1/fadd-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fadd.s | 110 +- llvm/test/MC/AArch64/SME2p1/fcvt.s | 20 +- .../MC/AArch64/SME2p1/fcvtl-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fcvtl.s | 20 +- .../test/MC/AArch64/SME2p1/fmla-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fmla.s | 300 +- .../test/MC/AArch64/SME2p1/fmls-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fmls.s | 300 +- .../MC/AArch64/SME2p1/fmopa-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fmopa.s | 36 +- .../MC/AArch64/SME2p1/fmops-diagnostics.s | 2 +- llvm/test/MC/AArch64/SME2p1/fmops.s | 36 +- .../test/MC/AArch64/SME2p1/fsub-diagnostics.s | 3 +- llvm/test/MC/AArch64/SME2p1/fsub.s | 108 +- llvm/test/MC/AArch64/ilp32-diagnostics.s | 8 + llvm/test/MC/AMDGPU/ds-err.s | 8 +- llvm/test/MC/AMDGPU/gfx11_asm_err.s | 4 +- llvm/test/MC/AMDGPU/gfx12_asm_vop3.s | 24 + llvm/test/MC/AMDGPU/gfx12_asm_vop3_dpp16.s | 24 + llvm/test/MC/AMDGPU/gfx12_asm_vop3_dpp8.s | 24 + llvm/test/MC/AMDGPU/gfx12_asm_vop3_err.s | 5 + llvm/test/MC/AMDGPU/pal-msgpack.s | 16 +- .../Disassembler/AMDGPU/gfx12_dasm_vop3.txt | 18 + .../AMDGPU/gfx12_dasm_vop3_dpp16.txt | 18 + .../AMDGPU/gfx12_dasm_vop3_dpp8.txt | 18 + llvm/test/MC/Disassembler/M68k/data.txt | 6 + llvm/test/MC/ELF/RISCV/gen-dwarf.s | 26 +- llvm/test/MC/M68k/Data/Classes/MxMove_RI.s | 3 + llvm/test/MC/RISCV/XTHeadVdot-valid.s | 28 +- llvm/test/MC/RISCV/align.s | 8 +- llvm/test/MC/RISCV/attribute-arch.s | 2 +- llvm/test/MC/RISCV/cfi-advance.s | 32 +- llvm/test/MC/RISCV/compress-cjal.s | 2 +- llvm/test/MC/RISCV/compress-rv32d.s | 8 +- llvm/test/MC/RISCV/compress-rv32f.s | 8 +- llvm/test/MC/RISCV/compress-rv32i.s | 70 +- llvm/test/MC/RISCV/compress-rv64i.s | 16 +- llvm/test/MC/RISCV/fde-reloc.s | 2 +- llvm/test/MC/RISCV/large-instructions.s | 29 + llvm/test/MC/RISCV/nop-slide.s | 22 +- llvm/test/MC/RISCV/option-pushpop.s | 8 +- llvm/test/MC/RISCV/option-rvc.s | 20 +- llvm/test/MC/RISCV/rv32dc-valid.s | 3 - llvm/test/MC/RISCV/rv32e-invalid.s | 64 +- llvm/test/MC/RISCV/rv32fc-valid.s | 3 - llvm/test/MC/RISCV/rv32zacas-invalid.s | 2 +- llvm/test/MC/RISCV/rv32zacas-valid.s | 12 +- llvm/test/MC/RISCV/rv64dc-valid.s | 3 - llvm/test/MC/RISCV/rv64zacas-valid.s | 6 +- llvm/test/MC/RISCV/rvv/add.s | 118 +- llvm/test/MC/RISCV/rvv/and.s | 12 +- llvm/test/MC/RISCV/rvv/clip.s | 24 +- llvm/test/MC/RISCV/rvv/compare.s | 166 +- llvm/test/MC/RISCV/rvv/convert.s | 86 +- llvm/test/MC/RISCV/rvv/div.s | 32 +- llvm/test/MC/RISCV/rvv/ext.s | 24 +- llvm/test/MC/RISCV/rvv/fadd.s | 24 +- llvm/test/MC/RISCV/rvv/fcompare.s | 50 +- llvm/test/MC/RISCV/rvv/fdiv.s | 12 +- llvm/test/MC/RISCV/rvv/fmacc.s | 96 +- llvm/test/MC/RISCV/rvv/fminmax.s | 16 +- llvm/test/MC/RISCV/rvv/fmul.s | 16 +- llvm/test/MC/RISCV/rvv/fmv.s | 6 +- llvm/test/MC/RISCV/rvv/fothers.s | 26 +- llvm/test/MC/RISCV/rvv/freduction.s | 26 +- llvm/test/MC/RISCV/rvv/fsub.s | 28 +- llvm/test/MC/RISCV/rvv/load.s | 128 +- llvm/test/MC/RISCV/rvv/macc.s | 60 +- llvm/test/MC/RISCV/rvv/mask.s | 52 +- llvm/test/MC/RISCV/rvv/minmax.s | 32 +- llvm/test/MC/RISCV/rvv/mul.s | 64 +- llvm/test/MC/RISCV/rvv/mv.s | 18 +- llvm/test/MC/RISCV/rvv/or.s | 12 +- llvm/test/MC/RISCV/rvv/others.s | 48 +- llvm/test/MC/RISCV/rvv/reduction.s | 42 +- llvm/test/MC/RISCV/rvv/shift.s | 86 +- llvm/test/MC/RISCV/rvv/sign-injection.s | 24 +- llvm/test/MC/RISCV/rvv/snippet.s | 24 +- llvm/test/MC/RISCV/rvv/store.s | 84 +- llvm/test/MC/RISCV/rvv/sub.s | 100 +- llvm/test/MC/RISCV/rvv/vsetvl.s | 50 +- llvm/test/MC/RISCV/rvv/xor.s | 16 +- llvm/test/MC/RISCV/rvv/xsfvcp.s | 56 +- llvm/test/MC/RISCV/rvv/xsfvfnrclip.s | 8 +- llvm/test/MC/RISCV/rvv/xsfvfwmacc.s | 2 +- llvm/test/MC/RISCV/rvv/xsfvqmacc.s | 16 +- llvm/test/MC/RISCV/rvv/zvbb.s | 14 +- llvm/test/MC/RISCV/rvv/zvbc.s | 8 +- llvm/test/MC/RISCV/rvv/zvfbfmin.s | 8 +- llvm/test/MC/RISCV/rvv/zvfbfwma.s | 16 +- llvm/test/MC/RISCV/rvv/zvkb.s | 18 +- llvm/test/MC/RISCV/rvv/zvkg.s | 4 +- llvm/test/MC/RISCV/rvv/zvkned.s | 26 +- llvm/test/MC/RISCV/rvv/zvknh.s | 6 +- llvm/test/MC/RISCV/rvv/zvksed.s | 8 +- llvm/test/MC/RISCV/rvv/zvksh.s | 6 +- llvm/test/MC/RISCV/rvv/zvlsseg.s | 1026 ++--- llvm/test/MC/RISCV/rvzabha-invalid.s | 4 +- llvm/test/MC/RISCV/rvzabha-valid.s | 12 +- llvm/test/MC/RISCV/rvzabha-zacas-valid.s | 16 +- llvm/test/MC/RISCV/scoped-relaxation.s | 6 +- llvm/test/MC/WebAssembly/global-ctor-dtor.ll | 12 +- llvm/test/MC/Xtensa/Core/invalid.s | 4 - llvm/test/MC/Xtensa/directive-literal.s | 42 + llvm/test/MC/Xtensa/invalid-literal.s | 10 + llvm/test/TableGen/ContextlessPredicates.td | 32 +- llvm/test/TableGen/DefaultOpsGlobalISel.td | 179 +- .../builtins/match-table-eraseroot.td | 7 +- .../builtins/match-table-replacerreg.td | 14 +- .../match-table-imms.td | 25 +- .../match-table-intrinsics.td | 14 +- .../match-table-miflags.td | 13 +- .../match-table-operand-types.td | 21 +- .../match-table-patfrag-root.td | 23 +- .../match-table-permutations.td | 146 +- .../match-table-temp-defs.td | 20 +- .../match-table-typeof.td | 11 +- .../GlobalISelCombinerEmitter/match-table.td | 29 +- .../GlobalISelEmitter-atomic_store.td | 2 +- .../TableGen/GlobalISelEmitter-frameindex.td | 29 + .../GlobalISelEmitter-immAllZeroOne.td | 12 +- ...lobalISelEmitter-immarg-literal-pattern.td | 4 +- .../GlobalISelEmitter-input-discard.td | 19 +- ...obalISelEmitter-multiple-output-discard.td | 25 +- .../GlobalISelEmitter-multiple-output.td | 79 +- .../GlobalISelEmitter-nested-subregs.td | 13 +- ...GlobalISelEmitter-notype-output-pattern.td | 8 +- .../GlobalISelEmitter-output-discard.td | 21 +- .../TableGen/GlobalISelEmitter-zero-reg.td | 17 +- llvm/test/TableGen/GlobalISelEmitter.td | 540 ++- .../GlobalISelEmitterCustomPredicate.td | 86 +- llvm/test/TableGen/GlobalISelEmitterFlags.td | 6 +- .../test/TableGen/GlobalISelEmitterHwModes.td | 36 +- .../GlobalISelEmitterMatchTableOptimizer.td | 27 +- ...rMatchTableOptimizerSameOperand-invalid.td | 159 +- ...elEmitterMatchTableOptimizerSameOperand.td | 2 +- .../GlobalISelEmitterOverloadedPtr.td | 8 +- .../TableGen/GlobalISelEmitterRegSequence.td | 17 +- .../GlobalISelEmitterSkippedPatterns.td | 6 + llvm/test/TableGen/GlobalISelEmitterSubreg.td | 73 +- .../TableGen/GlobalISelEmitterVariadic.td | 24 +- llvm/test/TableGen/HasNoUse.td | 15 +- llvm/test/TableGen/address-space-patfrags.td | 2 +- llvm/test/TableGen/gisel-physreg-input.td | 46 +- llvm/test/TableGen/immarg-predicated.td | 4 +- llvm/test/TableGen/immarg.td | 4 +- llvm/test/TableGen/riscv-target-def.td | 162 + llvm/test/TableGen/simplify-patfrag.td | 5 + .../AMDGPU/expand-atomic-i16-system.ll | 2 +- .../AtomicExpand/AMDGPU/expand-atomic-i16.ll | 14 +- .../AMDGPU/expand-atomic-i8-system.ll | 2 +- .../AtomicExpand/AMDGPU/expand-atomic-i8.ll | 4 +- .../AtomicExpand/AMDGPU/expand-atomic-mmra.ll | 204 + .../AMDGPU/no-expand-atomic-load.ll | 181 + .../AMDGPU/no-expand-atomic-store.ll | 179 + .../Transforms/AtomicExpand/SPARC/partword.ll | 22 +- .../CallSiteSplitting/callsite-split-debug.ll | 36 +- .../CodeGenPrepare/ARM/branch-on-zero.ll | 23 + .../CodeGenPrepare/RISCV/convert-to-eqz.ll | 80 + .../CodeGenPrepare/RISCV/noop-copy-sink.ll | 30 + .../Coroutines/coro-split-musttail10.ll | 11 +- .../Coroutines/coro-split-musttail11.ll | 55 - llvm/test/Transforms/FunctionAttrs/noundef.ll | 9 +- .../discover-transitive-phis.ll | 58 +- .../global-var-constants.ll | 8 +- .../FunctionSpecialization/literal-const.ll | 4 +- llvm/test/Transforms/GVN/condprop.ll | 227 +- llvm/test/Transforms/GlobalOpt/basictest.ll | 20 +- .../GlobalOpt/constantfold-initializers.ll | 5 +- .../GlobalOpt/stored-once-forward-value.ll | 6 +- llvm/test/Transforms/GlobalOpt/tls.ll | 12 +- llvm/test/Transforms/IRCE/pr89959.ll | 33 + .../Inline/inline-deferred-instsimplify.ll | 76 + llvm/test/Transforms/InstCombine/add4.ll | 162 + llvm/test/Transforms/InstCombine/array.ll | 160 + llvm/test/Transforms/InstCombine/bit_ceil.ll | 28 +- llvm/test/Transforms/InstCombine/bit_floor.ll | 16 +- .../Transforms/InstCombine/cmp-intrinsic.ll | 28 +- .../InstCombine/ctlz-cttz-bitreverse.ll | 12 +- .../InstCombine/ctlz-cttz-shifts.ll | 25 +- .../InstCombine/ctpop-bswap-bitreverse.ll | 8 +- .../test/Transforms/InstCombine/ctpop-cttz.ll | 18 +- .../test/Transforms/InstCombine/ctpop-pow2.ll | 4 +- llvm/test/Transforms/InstCombine/ctpop.ll | 64 +- llvm/test/Transforms/InstCombine/cttz-abs.ll | 34 +- .../Transforms/InstCombine/cttz-negative.ll | 14 +- llvm/test/Transforms/InstCombine/cttz.ll | 36 +- .../Transforms/InstCombine/fcmp-select.ll | 120 + llvm/test/Transforms/InstCombine/ffs-1.ll | 6 +- llvm/test/Transforms/InstCombine/ffs-i16.ll | 4 +- llvm/test/Transforms/InstCombine/fls-i16.ll | 4 +- llvm/test/Transforms/InstCombine/fls.ll | 2 +- llvm/test/Transforms/InstCombine/fneg.ll | 123 +- .../InstCombine/fold-ctpop-of-not.ll | 32 +- .../InstCombine/fold-log2-ceil-idiom.ll | 57 +- .../InstCombine/freeze-integer-intrinsics.ll | 16 +- llvm/test/Transforms/InstCombine/freeze.ll | 3 +- .../Transforms/InstCombine/gepofconstgepi8.ll | 292 ++ .../Transforms/InstCombine/icmp-ne-pow2.ll | 20 +- .../InstCombine/icmp-of-trunc-ext.ll | 325 ++ .../InstCombine/intrinsic-select.ll | 18 +- .../test/Transforms/InstCombine/intrinsics.ll | 24 +- llvm/test/Transforms/InstCombine/ispow2.ll | 166 +- .../Transforms/InstCombine/known-non-zero.ll | 18 +- .../InstCombine/known-phi-recurse.ll | 10 +- .../InstCombine/loadstore-alignment.ll | 40 +- .../InstCombine/memcpy-from-global.ll | 98 +- .../merging-multiple-stores-into-successor.ll | 36 +- .../Transforms/InstCombine/minmax-fold.ll | 2 +- llvm/test/Transforms/InstCombine/mul.ll | 80 +- .../InstCombine/reduction-add-sext-zext-i1.ll | 14 +- .../InstCombine/reduction-xor-sext-zext-i1.ll | 14 +- .../InstCombine/select-cmp-cttz-ctlz.ll | 94 +- .../InstCombine/select-ctlz-to-cttz.ll | 32 +- .../Transforms/InstCombine/select-select.ll | 7 +- llvm/test/Transforms/InstCombine/select.ll | 13 +- llvm/test/Transforms/InstCombine/sext.ll | 6 +- .../Transforms/InstCombine/shift-cttz-ctlz.ll | 15 +- llvm/test/Transforms/InstCombine/shift.ll | 68 +- .../InstCombine/simplify-demanded-fpclass.ll | 64 +- .../InstCombine/sub-of-negatible.ll | 6 +- llvm/test/Transforms/InstCombine/sub-xor.ll | 2 +- llvm/test/Transforms/InstCombine/sub.ll | 43 +- .../Transforms/InstCombine/vector-reverse.ll | 292 +- llvm/test/Transforms/InstCombine/xor.ll | 8 +- .../zext-ctlz-trunc-to-ctlz-add.ll | 14 +- .../InstSimplify/ConstProp/gep-alias.ll | 37 +- .../named-vector-shuffle-reverse.ll | 8 +- .../Transforms/InstSimplify/past-the-end.ll | 14 +- llvm/test/Transforms/InstSimplify/select.ll | 6 +- .../AArch64/fixed-deinterleave-intrinsics.ll | 96 +- .../scalable-deinterleave-intrinsics.ll | 68 +- .../AArch64/sve-interleaved-accesses.ll | 2 +- .../Transforms/LoopUnroll/unroll-loads-cse.ll | 480 +++ .../LoopUnroll/unroll-remove-redundant-dbg.ll | 45 + .../AArch64/conditional-branches-cost.ll | 857 ++++ .../AArch64/first-order-recurrence.ll | 6 +- .../AArch64/induction-costs-sve.ll | 916 +++++ .../LoopVectorize/AArch64/induction-costs.ll | 292 +- .../AArch64/reduction-recurrence-costs-sve.ll | 482 +++ .../AArch64/scalable-strict-fadd.ll | 8 +- .../LoopVectorize/AArch64/store-costs-sve.ll | 341 ++ .../AArch64/sve-interleaved-accesses.ll | 48 +- .../sve-interleaved-masked-accesses.ll | 16 +- .../AArch64/sve-tail-folding-option.ll | 24 +- .../AArch64/sve-vector-reverse-mask4.ll | 10 +- .../AArch64/sve-vector-reverse.ll | 2 +- .../LoopVectorize/AArch64/sve-widen-phi.ll | 4 +- .../ARM/tail-folding-counting-down.ll | 3 +- .../RISCV/riscv-vector-reverse.ll | 2 +- ...-force-tail-with-evl-reverse-load-store.ll | 8 +- .../LoopVectorize/X86/induction-costs.ll | 73 + .../LoopVectorize/X86/masked-store-cost.ll | 111 + .../LoopVectorize/reduction-inloop.ll | 6 +- .../LoopVectorize/runtime-checks-hoist.ll | 6 +- .../scalable-first-order-recurrence.ll | 12 +- .../LoopVectorize/trunc-extended-icmps.ll | 211 + .../unused-blend-mask-for-first-operand.ll | 6 +- .../version-stride-with-integer-casts.ll | 428 ++ .../LoopVectorize/vplan-infer-not-or-type.ll | 64 + .../cfi-nounwind-direct-call.ll | 24 +- llvm/test/Transforms/OpenMP/add_attributes.ll | 11 - .../AArch64/extra-unroll-simplifications.ll | 81 + .../PhaseOrdering/AArch64/quant_4x4.ll | 2 +- .../X86/loop-idiom-vs-indvars.ll | 2 +- .../icmp-ashr-breaking-select-idiom.ll | 4 +- .../PhaseOrdering/lower-table-based-cttz.ll | 2 +- .../Transforms/PhaseOrdering/min_max_loop.ll | 4 +- llvm/test/Transforms/SCCP/and-add-shl.ll | 4 +- .../Transforms/SCCP/ip-add-range-to-call.ll | 73 +- llvm/test/Transforms/SCCP/ip-ranges-casts.ll | 67 +- llvm/test/Transforms/SCCP/ipsccp-basic.ll | 6 +- llvm/test/Transforms/SCCP/switch.ll | 95 +- .../Transforms/SCCP/trunc-nuw-nsw-flags.ll | 4 +- ...ather-buildvector-with-minbitwidth-user.ll | 7 +- .../AArch64/gather-with-minbith-user.ll | 3 +- .../AArch64/user-node-not-in-bitwidths.ll | 7 +- .../AArch64/vec3-reorder-reshuffle.ll | 30 +- .../RISCV/minbw-with-and-and-scalar-trunc.ll | 44 + .../RISCV/strided-stores-vectorized.ll | 65 + .../RISCV/unsigned-icmp-signed-op.ll | 43 + .../SystemZ/minbitwidth-root-trunc.ll | 6 +- .../X86/alternate-opcode-sindle-bv.ll | 25 + .../X86/gather-node-same-as-vect-but-order.ll | 143 + .../X86/gep-with-extractelement-many-users.ll | 26 + .../X86/minbitwidth-node-with-multi-users.ll | 3 +- .../Transforms/SLPVectorizer/X86/pr46983.ll | 75 +- .../SampleProfile/pseudo-probe-profile.ll | 8 +- .../SimpleLoopUnswitch/endless-unswitch.ll | 93 + .../SimpleLoopUnswitch/partial-unswitch.ll | 130 + .../SimplifyCFG/UnreachableEliminate.ll | 226 + .../SimplifyCFG/hoist-dbgvalue-inlined.ll | 1 - .../Transforms/SimplifyCFG/hoist-dbgvalue.ll | 1 - llvm/test/Transforms/SimplifyCFG/mmra.ll | 150 + .../Transforms/SimplifyCFG/speculate-store.ll | 84 +- .../AArch64/shuffletoidentity.ll | 2 +- .../VectorCombine/X86/shuffle-of-binops.ll | 75 +- .../VectorCombine/X86/shuffle-of-shuffles.ll | 20 + llvm/test/Verifier/invalid-splice.ll | 14 +- llvm/test/Verifier/mmra-allowed.ll | 31 + llvm/test/Verifier/mmra.ll | 43 + llvm/test/lit.cfg.py | 3 + ...kip-unsupported-instructions-none-remain.s | 14 + .../X86/BtVer2/unsupported-instruction.s | 55 +- .../tools/llvm-profdata/memprof-merge-v0.test | 3 + .../tools/llvm-rc/Inputs/dialog-with-menu.rc | 16 + llvm/test/tools/llvm-rc/dialog-with-menu.test | 32 + llvm/tools/gold/gold-plugin.cpp | 6 +- .../llvm-exegesis/lib/BenchmarkRunner.cpp | 2 + .../llvm-exegesis/lib/SubprocessMemory.cpp | 7 +- llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 6 +- llvm/tools/llvm-lto2/llvm-lto2.cpp | 7 +- llvm/tools/llvm-mca/CodeRegion.h | 15 + llvm/tools/llvm-mca/llvm-mca.cpp | 39 +- llvm/tools/llvm-objdump/llvm-objdump.cpp | 52 + llvm/tools/llvm-profdata/llvm-profdata.cpp | 6 +- llvm/tools/llvm-rc/ResourceFileWriter.cpp | 10 +- llvm/tools/llvm-rc/ResourceFileWriter.h | 5 +- llvm/tools/llvm-rc/ResourceScriptParser.cpp | 7 + llvm/tools/llvm-rc/ResourceScriptParser.h | 1 + llvm/tools/llvm-rc/ResourceScriptStmt.cpp | 4 + llvm/tools/llvm-rc/ResourceScriptStmt.h | 13 + llvm/tools/llvm-rc/ResourceVisitor.h | 2 + llvm/tools/llvm-readtapi/llvm-readtapi.cpp | 2 - llvm/unittests/ADT/StringRefTest.cpp | 4 + llvm/unittests/Analysis/LoadsTest.cpp | 50 +- llvm/unittests/BinaryFormat/DwarfTest.cpp | 15 + .../CodeGen/GlobalISel/KnownBitsTest.cpp | 114 + llvm/unittests/CodeGen/MachineInstrTest.cpp | 52 + .../ExecutionEngine/Orc/CoreAPIsTest.cpp | 8 +- .../ExecutionEngine/Orc/OrcTestCommon.cpp | 15 + .../ExecutionEngine/Orc/OrcTestCommon.h | 15 +- .../ExecutionEngine/Orc/TaskDispatchTest.cpp | 2 +- llvm/unittests/Frontend/CMakeLists.txt | 2 +- llvm/unittests/Frontend/OpenMPComposeTest.cpp | 41 - .../Frontend/OpenMPCompositionTest.cpp | 100 + llvm/unittests/IR/CMakeLists.txt | 1 + llvm/unittests/IR/IntrinsicsTest.cpp | 85 +- .../MemoryModelRelaxationAnnotationsTest.cpp | 212 + llvm/unittests/IR/PatternMatch.cpp | 12 +- llvm/unittests/Object/ELFObjectFileTest.cpp | 43 + llvm/unittests/ProfileData/InstrProfTest.cpp | 110 +- llvm/unittests/ProfileData/MemProfTest.cpp | 118 +- llvm/unittests/Support/CMakeLists.txt | 1 - llvm/unittests/Support/MathExtrasTest.cpp | 2 +- llvm/unittests/Support/YAMLIOTest.cpp | 81 + llvm/unittests/TargetParser/CMakeLists.txt | 1 + .../RISCVISAInfoTest.cpp | 154 +- .../TargetParser/TargetParserTest.cpp | 58 +- llvm/utils/LLVMVisualizers/llvm.natvis | 6 +- llvm/utils/TableGen/ARMTargetDefEmitter.cpp | 63 + llvm/utils/TableGen/CMakeLists.txt | 2 + .../TableGen/Common/CodeGenDAGPatterns.cpp | 16 +- .../TableGen/Common/CodeGenDAGPatterns.h | 14 +- .../GlobalISel/GlobalISelMatchTable.cpp | 222 +- .../Common/GlobalISel/GlobalISelMatchTable.h | 34 +- .../TableGen/Common/SubtargetFeatureInfo.cpp | 2 +- llvm/utils/TableGen/DAGISelMatcherEmitter.cpp | 2 +- llvm/utils/TableGen/DXILEmitter.cpp | 4 +- llvm/utils/TableGen/GlobalISelEmitter.cpp | 11 + llvm/utils/TableGen/RISCVTargetDefEmitter.cpp | 171 +- .../clang-tidy/bugprone/BUILD.gn | 1 + .../clang-tidy/modernize/BUILD.gn | 1 + .../clang-tidy/readability/BUILD.gn | 1 + .../llvm/include/llvm/TargetParser/BUILD.gn | 20 +- llvm/utils/gn/secondary/llvm/lib/IR/BUILD.gn | 5 +- .../gn/secondary/llvm/lib/Support/BUILD.gn | 2 +- .../llvm/lib/Target/Hexagon/BUILD.gn | 1 + .../llvm/lib/Target/WebAssembly/BUILD.gn | 1 + .../secondary/llvm/lib/TargetParser/BUILD.gn | 1 + .../llvm/unittests/Frontend/BUILD.gn | 2 +- .../gn/secondary/llvm/unittests/IR/BUILD.gn | 3 +- .../secondary/llvm/unittests/Support/BUILD.gn | 1 - .../llvm/unittests/TargetParser/BUILD.gn | 1 + .../gn/secondary/llvm/utils/TableGen/BUILD.gn | 1 + llvm/utils/release/test-release.sh | 3 +- mlir/CMakeLists.txt | 3 + mlir/cmake/modules/AddMLIR.cmake | 38 + mlir/cmake/modules/CMakeLists.txt | 2 + mlir/cmake/modules/MLIRConfig.cmake.in | 1 + mlir/docs/DefiningDialects/Operations.md | 94 + .../Tutorials/UnderstandingTheIRStructure.md | 4 +- mlir/include/mlir-c/Dialect/LLVM.h | 7 + mlir/include/mlir-c/Dialect/SparseTensor.h | 11 +- mlir/include/mlir/Dialect/EmitC/IR/EmitC.td | 69 + .../mlir/Dialect/GPU/Transforms/Passes.td | 2 - .../mlir/Dialect/LLVMIR/LLVMIntrinsicOps.td | 4 +- mlir/include/mlir/Dialect/LLVMIR/VCIXOps.td | 4 +- .../mlir/Dialect/Linalg/IR/LinalgEnums.td | 12 +- .../Linalg/IR/LinalgNamedStructuredOps.yaml | 347 +- .../mlir/Dialect/Linalg/IR/LinalgOps.td | 4 +- .../TransformOps/LinalgTransformEnums.td | 9 + .../Linalg/TransformOps/LinalgTransformOps.td | 46 + .../Linalg/Transforms/RuntimeOpVerification.h | 21 + .../Dialect/Linalg/Transforms/Transforms.h | 12 + .../Dialect/OpenMP/OpenMPClauseOperands.h | 7 +- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 62 +- .../Dialect/OpenMP/OpenMPOpsInterfaces.td | 8 +- .../mlir/Dialect/Polynomial/IR/Polynomial.h | 5 +- .../mlir/Dialect/Polynomial/IR/Polynomial.td | 296 +- .../mlir/Dialect/SCF/Transforms/Passes.h | 3 + .../mlir/Dialect/SCF/Transforms/Passes.td | 5 + .../mlir/Dialect/SCF/Transforms/Transforms.h | 7 + .../Dialect/SparseTensor/IR/SparseTensor.h | 15 +- .../SparseTensor/IR/SparseTensorAttrDefs.td | 55 +- .../SparseTensor/IR/SparseTensorType.h | 22 + .../mlir/Dialect/Vector/Utils/VectorUtils.h | 2 +- .../mlir/Dialect/XeGPU/IR/CMakeLists.txt | 6 +- mlir/include/mlir/Dialect/XeGPU/IR/XeGPU.h | 3 +- .../mlir/Dialect/XeGPU/IR/XeGPUAttrs.td | 18 + .../mlir/Dialect/XeGPU/IR/XeGPUDialect.td | 4 +- .../include/mlir/Dialect/XeGPU/IR/XeGPUOps.td | 169 +- .../mlir/Dialect/XeGPU/IR/XeGPUTypes.td | 11 + mlir/include/mlir/IR/Builders.h | 18 +- .../mlir/IR/BuiltinLocationAttributes.td | 13 +- mlir/include/mlir/IR/OperationSupport.h | 9 +- mlir/include/mlir/IR/Value.h | 8 +- mlir/include/mlir/InitAllDialects.h | 2 + .../mlir/Interfaces/MemorySlotInterfaces.td | 1 + .../RuntimeVerifiableOpInterface.td | 6 + .../mlir/Interfaces/TilingInterface.td | 67 +- mlir/include/mlir/TableGen/CodeGenHelpers.h | 12 +- .../mlir/Tools/lsp-server-support/Transport.h | 12 +- mlir/lib/Bindings/Python/DialectLLVM.cpp | 43 +- .../Bindings/Python/DialectSparseTensor.cpp | 27 +- mlir/lib/CAPI/Dialect/LLVM.cpp | 8 + mlir/lib/CAPI/Dialect/SparseTensor.cpp | 26 +- .../ComplexToStandard/ComplexToStandard.cpp | 2 +- .../MemRefToEmitC/MemRefToEmitC.cpp | 70 +- .../Conversion/SCFToOpenMP/SCFToOpenMP.cpp | 51 +- .../TosaToLinalg/TosaToLinalgNamed.cpp | 15 +- .../VectorToLLVM/ConvertVectorToLLVM.cpp | 2 +- .../Dialect/Arith/IR/ArithCanonicalization.td | 1 + .../ArmSME/Transforms/OuterProductFusion.cpp | 3 +- .../Transforms/OneShotAnalysis.cpp | 21 +- mlir/lib/Dialect/EmitC/IR/EmitC.cpp | 118 +- .../Dialect/GPU/Transforms/ModuleToBinary.cpp | 5 +- mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp | 3 +- mlir/lib/Dialect/LLVMIR/IR/LLVMMemorySlot.cpp | 214 +- mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp | 25 +- .../TransformOps/LinalgTransformOps.cpp | 26 + .../Dialect/Linalg/Transforms/CMakeLists.txt | 3 + .../Transforms/RuntimeOpVerification.cpp | 135 + .../Linalg/Transforms/TilingInterfaceImpl.cpp | 106 +- .../Linalg/Transforms/TransposeMatmul.cpp | 161 + .../Linalg/Transforms/Vectorization.cpp | 10 +- .../Dialect/MemRef/IR/MemRefMemorySlot.cpp | 2 + .../MemRef/Transforms/EmulateNarrowType.cpp | 32 +- .../Transforms/ExpandStridedMetadata.cpp | 201 +- .../Transforms/RuntimeOpVerification.cpp | 54 +- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 222 +- mlir/lib/Dialect/Polynomial/IR/CMakeLists.txt | 1 + .../Polynomial/IR/PolynomialAttributes.cpp | 2 +- .../Polynomial/IR/PolynomialDialect.cpp | 9 + .../Dialect/Polynomial/IR/PolynomialOps.cpp | 95 +- .../SCF/TransformOps/SCFTransformOps.cpp | 33 +- .../lib/Dialect/SCF/Transforms/CMakeLists.txt | 1 + .../Dialect/SCF/Transforms/ForallToFor.cpp | 79 + .../SparseTensor/IR/SparseTensorDialect.cpp | 101 +- .../Transforms/SparseTensorRewriting.cpp | 114 +- .../Transforms/Sparsification.cpp | 44 +- .../Transforms/Utils/SparseTensorIterator.h | 7 +- mlir/lib/Dialect/Tensor/IR/TensorOps.cpp | 3 + .../Tensor/IR/TensorTilingInterfaceImpl.cpp | 12 +- .../Transforms/LowerVectorMultiReduction.cpp | 15 +- .../Vector/Transforms/VectorLinearize.cpp | 16 +- mlir/lib/Dialect/Vector/Utils/VectorUtils.cpp | 4 +- mlir/lib/Dialect/XeGPU/IR/CMakeLists.txt | 1 + mlir/lib/Dialect/XeGPU/IR/XeGPUOps.cpp | 22 + mlir/lib/IR/Builders.cpp | 20 +- .../RuntimeVerifiableOpInterface.cpp | 21 + mlir/lib/TableGen/CodeGenHelpers.cpp | 15 +- mlir/lib/Target/Cpp/TranslateToCpp.cpp | 55 +- mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp | 4 + .../OpenMP/OpenMPToLLVMIRTranslation.cpp | 68 +- .../Tools/lsp-server-support/Transport.cpp | 6 +- mlir/lib/Transforms/Mem2Reg.cpp | 21 +- .../Transforms/Utils/DialectConversion.cpp | 4 + mlir/python/mlir/dialects/LLVMOps.td | 1 + .../linalg/opdsl/lang/comprehension.py | 7 + .../linalg/opdsl/ops/core_named_ops.py | 114 +- mlir/python/mlir/dialects/llvm.py | 8 + .../transform/interpreter/__init__.py | 2 +- mlir/test/CAPI/execution_engine.c | 7 +- mlir/test/CAPI/sparse_tensor.c | 17 +- .../MemRefToEmitC/memref-to-emitc-failed.mlir | 5 + .../MemRefToEmitC/memref-to-emitc.mlir | 19 + .../OpenMPToLLVM/convert-to-llvmir.mlir | 64 +- .../Conversion/SCFToOpenMP/reductions.mlir | 5 + .../Conversion/SCFToOpenMP/scf-to-openmp.mlir | 31 +- .../TosaToLinalg/tosa-to-linalg-named.mlir | 13 + .../VectorToArmSME/vector-to-arm-sme.mlir | 623 +++ .../VectorToLLVM/vector-to-llvm.mlir | 4 +- mlir/test/Dialect/Arith/canonicalize.mlir | 103 + .../Dialect/ArmSME/outer-product-fusion.mlir | 32 +- .../Dialect/ArmSME/vector-ops-to-llvm.mlir | 877 ---- mlir/test/Dialect/EmitC/invalid_ops.mlir | 15 + mlir/test/Dialect/EmitC/ops.mlir | 14 + mlir/test/Dialect/LLVMIR/invalid.mlir | 16 +- .../Dialect/LLVMIR/legalize-for-export.mlir | 19 +- mlir/test/Dialect/LLVMIR/mem2reg.mlir | 154 +- mlir/test/Dialect/LLVMIR/roundtrip.mlir | 8 +- .../Dialect/Linalg/generalize-named-ops.mlir | 201 + .../Dialect/Linalg/match-ops-interpreter.mlir | 22 + mlir/test/Dialect/Linalg/named-ops-fail.mlir | 145 + mlir/test/Dialect/Linalg/named-ops.mlir | 285 ++ .../Dialect/Linalg/runtime-verification.mlir | 43 + .../Dialect/Linalg/transpose-matmul-a.mlir | 14 + .../Dialect/Linalg/transpose-matmul-b.mlir | 14 + .../test/Dialect/Linalg/transpose-matmul.mlir | 179 + .../Dialect/MemRef/emulate-narrow-type.mlir | 20 + .../MemRef/expand-strided-metadata.mlir | 24 +- mlir/test/Dialect/OpenMP/invalid.mlir | 302 +- mlir/test/Dialect/OpenMP/ops.mlir | 593 +-- mlir/test/Dialect/Polynomial/ops.mlir | 82 + mlir/test/Dialect/Polynomial/ops_errors.mlir | 53 + mlir/test/Dialect/Polynomial/types.mlir | 14 + mlir/test/Dialect/SCF/forall-to-for.mlir | 57 + ...fuse_sparse_concat_with_extract_slice.mlir | 23 + .../fuse_sparse_convert_into_producer.mlir | 78 + .../SparseTensor/no_fold_into_consumer.mlir | 47 - .../SparseTensor/roundtrip_encoding.mlir | 58 + mlir/test/Dialect/Tensor/canonicalize.mlir | 9 + .../vector-multi-reduction-lowering.mlir | 17 + mlir/test/Dialect/XeGPU/XeGPUOps.mlir | 59 +- mlir/test/Dialect/XeGPU/invalid.mlir | 28 + mlir/test/Examples/NVGPU/Ch0.py | 50 + mlir/test/Examples/NVGPU/Ch1.py | 66 + mlir/test/Examples/NVGPU/Ch2.py | 93 + mlir/test/Examples/NVGPU/Ch3.py | 129 + mlir/test/Examples/NVGPU/Ch4.py | 323 ++ mlir/test/Examples/NVGPU/Ch5.py | 321 ++ mlir/test/Examples/NVGPU/lit.local.cfg | 4 + mlir/test/Examples/NVGPU/tools/lit.local.cfg | 3 + mlir/test/Examples/NVGPU/tools/nvdsl.py | 456 +++ .../Examples/NVGPU/tools/nvgpucompiler.py | 45 + .../Linalg/CPU/runtime-verification.mlir | 298 ++ mlir/test/Integration/lit.local.cfg | 46 +- mlir/test/Target/Cpp/global.mlir | 38 + .../Target/LLVMIR/Import/import-failure.ll | 8 +- .../LLVMIR/omptarget-parallel-wsloop.mlir | 11 +- .../LLVMIR/omptarget-wsloop-collapsed.mlir | 17 +- mlir/test/Target/LLVMIR/omptarget-wsloop.mlir | 18 +- .../LLVMIR/openmp-data-target-device.mlir | 31 +- mlir/test/Target/LLVMIR/openmp-llvm.mlir | 741 ++-- mlir/test/Target/LLVMIR/openmp-nested.mlir | 30 +- mlir/test/Target/LLVMIR/openmp-reduction.mlir | 113 +- .../openmp-wsloop-reduction-cleanup.mlir | 9 +- mlir/test/Transforms/test-legalizer.mlir | 10 + mlir/test/lib/Dialect/Test/CMakeLists.txt | 6 +- mlir/test/lib/Dialect/Test/TestDialect.cpp | 5 +- mlir/test/lib/Dialect/Test/TestOpDefs.cpp | 13 + mlir/test/lib/Dialect/Test/TestOps.cpp | 1 - mlir/test/lib/Dialect/Test/TestOps.td | 6 + mlir/test/lib/Dialect/Test/TestPatterns.cpp | 4 + mlir/test/mlir-tblgen/shard-op-defs.td | 33 + mlir/test/python/dialects/llvm.py | 43 + .../python/dialects/sparse_tensor/dialect.py | 73 +- .../python/dialects/transform_interpreter.py | 15 + mlir/tools/mlir-src-sharder/CMakeLists.txt | 14 + .../mlir-src-sharder/mlir-src-sharder.cpp | 114 + mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 164 +- mlir/tools/mlir-tblgen/OpGenHelpers.cpp | 25 +- mlir/tools/mlir-tblgen/OpGenHelpers.h | 5 + mlir/unittests/CMakeLists.txt | 1 + mlir/unittests/Tools/CMakeLists.txt | 1 + .../Tools/lsp-server-support/CMakeLists.txt | 6 + .../Tools/lsp-server-support/Transport.cpp | 134 + offload/CMakeLists.txt | 20 + offload/include/Shared/Targets.def.in | 20 + offload/plugins-nextgen/CMakeLists.txt | 9 +- offload/plugins-nextgen/common/CMakeLists.txt | 1 + offload/plugins-nextgen/host/CMakeLists.txt | 40 +- offload/src/CMakeLists.txt | 22 +- offload/src/PluginManager.cpp | 27 +- offload/test/unified_shared_memory/api.c | 9 - .../test/unified_shared_memory/close_manual.c | 6 - .../unified_shared_memory/shared_update.c | 9 - openmp/runtime/src/kmp_affinity.cpp | 10 +- openmp/runtime/src/kmp_affinity.h | 2 + .../llvm-project-overlay/libc/BUILD.bazel | 29 +- .../libc/libc_build_rules.bzl | 5 +- .../libc/libc_configure_options.bzl | 49 + .../libc/test/UnitTest/BUILD.bazel | 8 +- .../libc/test/libc_test_rules.bzl | 5 +- .../libc/test/src/fenv/BUILD.bazel | 76 +- .../libc/test/src/math/BUILD.bazel | 1 + .../lldb/source/Plugins/BUILD.bazel | 4 + .../llvm-project-overlay/llvm/BUILD.bazel | 54 +- .../llvm/unittests/BUILD.bazel | 26 + .../llvm-project-overlay/mlir/BUILD.bazel | 74 +- .../llvm-project-overlay/mlir/build_defs.bzl | 3 +- .../mlir/python/BUILD.bazel | 7 - .../llvm-project-overlay/mlir/tblgen.bzl | 133 + .../mlir/test/BUILD.bazel | 27 +- .../mlir/test/Dialect/BUILD.bazel | 2 + 2697 files changed, 122727 insertions(+), 48163 deletions(-) rename bolt/test/RISCV/{unnamed-sym-no-entry.c => fake-label-no-entry.c} (85%) create mode 100644 bolt/test/X86/indirect-goto-pie.test delete mode 100644 bolt/test/runtime/X86/Inputs/indirect_goto.c delete mode 100644 bolt/test/runtime/X86/indirect-goto-pie.test create mode 100644 clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.h create mode 100644 clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.h create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp create mode 100644 clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h create mode 100644 clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/min-max-use-initializer-list.rst create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst create mode 100644 clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp create mode 100644 clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/5/.clang-tidy create mode 100644 clang/include/clang/AST/DeclID.h create mode 100644 clang/include/clang/Basic/PointerAuthOptions.h create mode 100644 clang/include/clang/CIR/Dialect/CMakeLists.txt create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRDialect.h create mode 100644 clang/include/clang/CIR/Dialect/IR/CIRDialect.td create mode 100644 clang/include/clang/CIR/Dialect/IR/CIROps.td create mode 100644 clang/include/clang/CIR/Dialect/IR/CMakeLists.txt create mode 100644 clang/lib/CIR/Dialect/CMakeLists.txt create mode 100644 clang/lib/CIR/Dialect/IR/CIRDialect.cpp create mode 100644 clang/lib/CIR/Dialect/IR/CMakeLists.txt create mode 100644 clang/test/AST/Interp/opencl.cl create mode 100644 clang/test/AST/ast-dump-fpfeatures.m create mode 100644 clang/test/AST/ast-dump-late-parsing.cpp create mode 100644 clang/test/AST/ast-dump-pragma-unroll.cpp create mode 100644 clang/test/Analysis/Checkers/WebKit/call-args-regression-traverse-decl-crash.cpp create mode 100644 clang/test/CXX/drs/cwg2149.cpp create mode 100644 clang/test/CXX/stmt.stmt/stmt.return/p6.cpp create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vcreate.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vget.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vle16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlmul_ext_v.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlmul_trunc_v.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vloxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg2e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg3e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg4e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg5e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg6e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg7e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlseg8e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vlsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vluxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vreinterpret.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vset.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsoxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vssseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vsuxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/non-overloaded/bfloat16/vundefined.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vget.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vle16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vle16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlmul_ext_v.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlmul_trunc_v.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vloxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg2e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg3e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg4e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg5e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg6e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg7e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlseg8e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vlsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vluxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vreinterpret.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vset.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsoxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vssseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/non-policy/overloaded/bfloat16/vsuxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vle16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vle16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vloxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg2e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg3e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg4e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg5e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg6e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg7e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlseg8e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vlsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/non-overloaded/bfloat16/vluxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vle16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vle16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vloxseg8ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlse16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg2e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg3e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg4e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg5e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg6e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg7e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlseg8e16ff.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg2e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg3e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg4e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg5e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg6e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg7e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vlsseg8e16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg2ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg3ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg4ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg5ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg6ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg7ei16.c create mode 100644 clang/test/CodeGen/RISCV/rvv-intrinsics-autogenerated/policy/overloaded/bfloat16/vluxseg8ei16.c create mode 100644 clang/test/CodeGenCXX/control-flow-in-stmt-expr.cpp create mode 100644 clang/test/CodeGenCXX/dependent-template-alias.cpp create mode 100644 clang/test/CodeGenCoroutines/coro-suspend-cleanups.cpp create mode 100644 clang/test/CodeGenObjCXX/msabi-stret-arm64.mm delete mode 100644 clang/test/Driver/claim-unused.c create mode 100644 clang/test/Driver/gcc-param.c create mode 100644 clang/test/Frontend/ast-dump-on-llvm.ll create mode 100644 clang/test/Misc/cc1as-relax-all.s create mode 100644 clang/test/Modules/pr88400.cppm create mode 100644 clang/test/Modules/prune-non-affecting-module-map-files-textual.c create mode 100644 clang/test/Preprocessor/hardware_interference.cpp create mode 100644 clang/test/Sema/constant_builtins_vector.cpp delete mode 100755 clang/test/TestRunner.sh create mode 100644 compiler-rt/test/ctx_profile/CMakeLists.txt create mode 100644 compiler-rt/test/ctx_profile/Unit/lit.site.cfg.py.in create mode 100644 compiler-rt/test/memprof/Unit/lit.site.cfg.py.in create mode 100644 flang/include/flang/Optimizer/Builder/Runtime/Main.h create mode 100644 flang/lib/Optimizer/Builder/Runtime/Main.cpp delete mode 100644 flang/runtime/FortranMain/CMakeLists.txt delete mode 100644 flang/runtime/FortranMain/Fortran_main.c create mode 100644 flang/test/Lower/Intrinsics/shape.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/array-bounds.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/atomic-capture.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/atomic-read.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/atomic-update.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/atomic-write.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/copyin.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/critical.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/declare-target-data.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/declare-target-func-and-subr.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/declare-target-implicit-func-and-subr-cap-enter.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/declare-target-implicit-func-and-subr-cap.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/default-clause.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/delayed-privatization-firstprivate.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/delayed-privatization-private.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/firstprivate-commonblock.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/flush.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/if-clause.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/is-device.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/lastprivate-commonblock.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/location.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/loop-combined.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/map-component-ref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/master.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/omp-declare-target-program-var.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/omp-is-gpu.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/ordered-threads.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-firstprivate-clause-scalar.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-lastprivate-clause-scalar.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-private-clause-fixes.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-private-clause.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-reduction-add-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-reduction-add.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-sections.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-wsloop-firstpriv.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel-wsloop.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/parallel.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/pre-fir-tree-loop.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/pre-fir-tree01.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/private-commonblock.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/requires-common.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/requires-notarget.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/requires.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/rtl-flags.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/sections-pft.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/sections.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/simd.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/simple-barrier.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/single.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/stop-stmt-in-region.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/target.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/target_cpu_features.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/task.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/taskgroup.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/taskwait.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/taskyield.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/teams.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-char-array-chararray.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-commonblock.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-integer-different-kinds.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-non-global.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-pointer-allocatable.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-real-logical-complex-derivedtype.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-use-association-2.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/threadprivate-use-association.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/unstructured.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-chunks.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-collapse.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-monotonic.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-nonmonotonic.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-ordered.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-add-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-add.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-iand.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-ieor.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-ior.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-eqv.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-logical-neqv.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-max-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-max.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-min-byref.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-reduction-min.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-simd.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop-variable.f90 delete mode 100644 flang/test/Lower/OpenMP/FIR/wsloop.f90 delete mode 100644 flang/test/Lower/OpenMP/Todo/reduction-allocatable.f90 create mode 100644 flang/test/Lower/OpenMP/cfg-conversion-omp.private.f90 create mode 100644 flang/test/Lower/OpenMP/default-clause-implied-do-fix.f90 create mode 100644 flang/test/Lower/OpenMP/function-filtering-3.f90 create mode 100644 flang/test/Lower/OpenMP/parallel-reduction-allocatable-array.f90 create mode 100644 flang/test/Lower/OpenMP/parallel-reduction-array-lb.f90 create mode 100644 flang/test/Lower/OpenMP/wsloop-reduction-allocatable.f90 create mode 100644 flang/test/Preprocessing/backslash-contin1.F90 create mode 100644 flang/test/Semantics/OpenMP/firstprivate02.f90 create mode 100644 flang/test/Semantics/OpenMP/lastprivate03.f90 create mode 100644 flang/test/Semantics/arg-convert.f90 create mode 100644 libc/docs/setjmp.rst create mode 100644 libc/include/llvm-libc-macros/assert-macros.h create mode 100644 libc/test/UnitTest/FEnvSafeTest.cpp create mode 100644 libc/test/UnitTest/FEnvSafeTest.h create mode 100644 libc/test/include/assert_test.cpp create mode 100644 libc/test/src/fenv/excepts.h create mode 100644 libc/utils/docgen/setjmp.json create mode 100644 libcxx/benchmarks/std_format_spec_string_unicode_escape.bench.cpp create mode 100644 libcxx/test/libcxx/utilities/format/format.string/format.string.std/escaped_output.pass.cpp create mode 100644 libcxx/test/libcxx/utilities/no_destroy.pass.cpp create mode 100644 libcxx/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.get.area/setg.assert.pass.cpp create mode 100644 libcxx/test/std/input.output/stream.buffers/streambuf/streambuf.protected/streambuf.put.area/setp.assert.pass.cpp create mode 100644 libcxx/test/std/ranges/range.adaptors/range.adaptor.object/range_adaptor_closure.pass.cpp create mode 100644 lld/test/ELF/lto/i386-global-offset-table.ll create mode 100644 lld/test/ELF/lto/x86-64-global-offset-table.ll delete mode 100644 lldb/docs/lldb-gdb-remote.txt delete mode 100644 lldb/docs/lldb-platform-packets.txt create mode 100644 lldb/docs/resources/lldbgdbremote.md create mode 100644 lldb/docs/resources/lldbplatformpackets.md create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/Makefile create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/TestClearSBValueNonAddressableBits.py create mode 100644 lldb/test/API/clear-sbvalue-nonaddressable-bits/main.c create mode 100644 lldb/test/API/tools/lldb-dap/stepInTargets/Makefile create mode 100644 lldb/test/API/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py create mode 100644 lldb/test/API/tools/lldb-dap/stepInTargets/main.cpp create mode 100644 llvm/docs/MemoryModelRelaxationAnnotations.rst create mode 100644 llvm/include/llvm/IR/MemoryModelRelaxationAnnotations.h create mode 100644 llvm/include/llvm/Support/RISCVISAUtils.h rename llvm/include/llvm/{Support => TargetParser}/RISCVISAInfo.h (79%) create mode 100644 llvm/lib/IR/MemoryModelRelaxationAnnotations.cpp create mode 100644 llvm/lib/Support/RISCVISAUtils.cpp create mode 100644 llvm/lib/Target/AArch64/AArch64Features.td create mode 100644 llvm/lib/Target/AArch64/AArch64Processors.td create mode 100644 llvm/lib/Target/ARM/ARMArchitectures.td create mode 100644 llvm/lib/Target/ARM/ARMFeatures.td create mode 100644 llvm/lib/Target/ARM/ARMProcessors.td create mode 100644 llvm/lib/Target/Hexagon/HexagonCopyHoisting.cpp create mode 100644 llvm/lib/Target/RISCV/RISCVProfiles.td create mode 100644 llvm/lib/Target/WebAssembly/WebAssemblyCleanCodeAfterTrap.cpp create mode 100644 llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.cpp create mode 100644 llvm/lib/Target/Xtensa/MCTargetDesc/XtensaTargetStreamer.h create mode 100644 llvm/lib/Target/Xtensa/XtensaCallingConv.td create mode 100644 llvm/lib/Target/Xtensa/XtensaConstantPoolValue.cpp create mode 100644 llvm/lib/Target/Xtensa/XtensaConstantPoolValue.h create mode 100644 llvm/lib/Target/Xtensa/XtensaOperators.td create mode 100644 llvm/lib/Target/Xtensa/XtensaUtils.cpp create mode 100644 llvm/lib/Target/Xtensa/XtensaUtils.h rename llvm/lib/{Support => TargetParser}/RISCVISAInfo.cpp (65%) create mode 100644 llvm/test/Analysis/CostModel/X86/load-broadcast.ll create mode 100644 llvm/test/Analysis/LoopAccessAnalysis/different-strides-safe-dep-due-to-backedge-taken-count.ll create mode 100644 llvm/test/Bitcode/upgrade-vector-interleave2-deinterleave2-intrinsics.ll create mode 100644 llvm/test/Bitcode/upgrade-vector-reverse-intrinsic.ll create mode 100644 llvm/test/Bitcode/upgrade-vector-splice-intrinsic.ll create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/legalize-bitcast.mir create mode 100644 llvm/test/CodeGen/AArch64/concatbinop.ll create mode 100644 llvm/test/CodeGen/AArch64/sve2-intrinsics-while-reversed.ll create mode 100644 llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-trap-gfx11.mir create mode 100644 llvm/test/CodeGen/AMDGPU/GlobalISel/mmra.ll create mode 100644 llvm/test/CodeGen/AMDGPU/fp_trunc_store_bf16.ll create mode 100644 llvm/test/CodeGen/AMDGPU/hard-clauses-img-gfx10.mir create mode 100644 llvm/test/CodeGen/AMDGPU/hard-clauses-img-gfx11.mir create mode 100644 llvm/test/CodeGen/AMDGPU/hard-clauses-img-gfx12.mir create mode 100644 llvm/test/CodeGen/AMDGPU/live-interval-bug-in-rename-independent-subregs.mir create mode 100644 llvm/test/CodeGen/AMDGPU/mmra.ll create mode 100644 llvm/test/CodeGen/AMDGPU/mode-register-fpconstrain.ll create mode 100644 llvm/test/CodeGen/Hexagon/arg-copy-elison.ll create mode 100644 llvm/test/CodeGen/Hexagon/hexagon-copy-hoisting.mir create mode 100644 llvm/test/CodeGen/LoongArch/sextw-removal.ll create mode 100644 llvm/test/CodeGen/Mips/mipsr6-minmaxnum.ll create mode 100644 llvm/test/CodeGen/NVPTX/rsqrt-opt.ll create mode 100644 llvm/test/CodeGen/NVPTX/rsqrt.ll create mode 100644 llvm/test/CodeGen/PowerPC/fminimum-fmaximum-f128.ll create mode 100644 llvm/test/CodeGen/PowerPC/fminimum-fmaximum.ll create mode 100644 llvm/test/CodeGen/PowerPC/peephole-counter-XToI.mir create mode 100644 llvm/test/CodeGen/PowerPC/peephole-counter-perOp.mir create mode 100644 llvm/test/CodeGen/RISCV/pr84653_pr85190.ll create mode 100644 llvm/test/CodeGen/RISCV/pr89833.ll create mode 100644 llvm/test/CodeGen/RISCV/rvv/commutable.ll create mode 100644 llvm/test/CodeGen/RISCV/rvv/vector-reassociations.ll create mode 100644 llvm/test/CodeGen/SPIRV/pointers/argument-ptr-to-struct.ll create mode 100644 llvm/test/CodeGen/SPIRV/pointers/global-ptrtoint.ll create mode 100644 llvm/test/CodeGen/SPIRV/pointers/variables-storage-class.ll create mode 100644 llvm/test/CodeGen/SPIRV/printf.ll create mode 100644 llvm/test/CodeGen/SPIRV/transcoding/spirv-event-null.ll create mode 100644 llvm/test/CodeGen/SPIRV/types/or-i1.ll create mode 100644 llvm/test/CodeGen/SystemZ/zos-no-eh-label.ll create mode 100644 llvm/test/CodeGen/X86/combine-or-shuffle.ll create mode 100644 llvm/test/CodeGen/Xtensa/call.ll create mode 100644 llvm/test/CodeGen/Xtensa/calling-conv.ll create mode 100644 llvm/test/CodeGen/Xtensa/constantpool.ll create mode 100644 llvm/test/CodeGen/Xtensa/stack-access.ll rename llvm/test/DebugInfo/Symbolize/ELF/{riscv-empty-name-symbol.s => riscv-temporary-symbol.s} (71%) create mode 100644 llvm/test/DebugInfo/X86/call-origin-linkage-names.ll create mode 100644 llvm/test/DebugInfo/X86/invalid-cu-abbrev-contribution-dwp.s create mode 100644 llvm/test/DebugInfo/X86/invalid-cu-abbrev-offset-dwp.s create mode 100644 llvm/test/Instrumentation/HWAddressSanitizer/fixed-shadow.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail1.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail10.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail11.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail12.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail13.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail2.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail3.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail4.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail5.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail6.ll delete mode 100644 llvm/test/Instrumentation/InstrProfiling/Coro/coro-split-musttail7.ll create mode 100644 llvm/test/Instrumentation/MemorySanitizer/X86/mmx-intrinsics.ll create mode 100644 llvm/test/Instrumentation/MemorySanitizer/vscale.ll create mode 100644 llvm/test/MC/RISCV/large-instructions.s create mode 100644 llvm/test/MC/Xtensa/directive-literal.s create mode 100644 llvm/test/MC/Xtensa/invalid-literal.s create mode 100644 llvm/test/TableGen/GlobalISelEmitter-frameindex.td create mode 100644 llvm/test/TableGen/riscv-target-def.td create mode 100644 llvm/test/Transforms/AtomicExpand/AMDGPU/expand-atomic-mmra.ll create mode 100644 llvm/test/Transforms/AtomicExpand/AMDGPU/no-expand-atomic-load.ll create mode 100644 llvm/test/Transforms/AtomicExpand/AMDGPU/no-expand-atomic-store.ll create mode 100644 llvm/test/Transforms/CodeGenPrepare/RISCV/convert-to-eqz.ll create mode 100644 llvm/test/Transforms/CodeGenPrepare/RISCV/noop-copy-sink.ll delete mode 100644 llvm/test/Transforms/Coroutines/coro-split-musttail11.ll create mode 100644 llvm/test/Transforms/IRCE/pr89959.ll create mode 100644 llvm/test/Transforms/Inline/inline-deferred-instsimplify.ll create mode 100644 llvm/test/Transforms/InstCombine/gepofconstgepi8.ll create mode 100644 llvm/test/Transforms/LoopUnroll/unroll-loads-cse.ll create mode 100644 llvm/test/Transforms/LoopUnroll/unroll-remove-redundant-dbg.ll create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/conditional-branches-cost.ll create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/induction-costs-sve.ll create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/reduction-recurrence-costs-sve.ll create mode 100644 llvm/test/Transforms/LoopVectorize/AArch64/store-costs-sve.ll create mode 100644 llvm/test/Transforms/LoopVectorize/X86/masked-store-cost.ll create mode 100644 llvm/test/Transforms/LoopVectorize/trunc-extended-icmps.ll create mode 100644 llvm/test/Transforms/LoopVectorize/version-stride-with-integer-casts.ll create mode 100644 llvm/test/Transforms/LoopVectorize/vplan-infer-not-or-type.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/RISCV/minbw-with-and-and-scalar-trunc.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/RISCV/strided-stores-vectorized.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/RISCV/unsigned-icmp-signed-op.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/alternate-opcode-sindle-bv.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/gather-node-same-as-vect-but-order.ll create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/gep-with-extractelement-many-users.ll create mode 100644 llvm/test/Transforms/SimplifyCFG/mmra.ll create mode 100644 llvm/test/Verifier/mmra-allowed.ll create mode 100644 llvm/test/Verifier/mmra.ll create mode 100644 llvm/test/tools/llvm-mca/X86/BtVer2/skip-unsupported-instructions-none-remain.s create mode 100644 llvm/test/tools/llvm-rc/Inputs/dialog-with-menu.rc create mode 100644 llvm/test/tools/llvm-rc/dialog-with-menu.test delete mode 100644 llvm/unittests/Frontend/OpenMPComposeTest.cpp create mode 100644 llvm/unittests/Frontend/OpenMPCompositionTest.cpp create mode 100644 llvm/unittests/IR/MemoryModelRelaxationAnnotationsTest.cpp rename llvm/unittests/{Support => TargetParser}/RISCVISAInfoTest.cpp (86%) create mode 100644 llvm/utils/TableGen/ARMTargetDefEmitter.cpp create mode 100644 mlir/include/mlir/Dialect/Linalg/Transforms/RuntimeOpVerification.h create mode 100644 mlir/lib/Dialect/Linalg/Transforms/RuntimeOpVerification.cpp create mode 100644 mlir/lib/Dialect/Linalg/Transforms/TransposeMatmul.cpp create mode 100644 mlir/lib/Dialect/SCF/Transforms/ForallToFor.cpp delete mode 100644 mlir/test/Dialect/ArmSME/vector-ops-to-llvm.mlir create mode 100644 mlir/test/Dialect/Linalg/runtime-verification.mlir create mode 100644 mlir/test/Dialect/Linalg/transpose-matmul-a.mlir create mode 100644 mlir/test/Dialect/Linalg/transpose-matmul-b.mlir create mode 100644 mlir/test/Dialect/Linalg/transpose-matmul.mlir create mode 100644 mlir/test/Dialect/Polynomial/ops.mlir create mode 100644 mlir/test/Dialect/Polynomial/ops_errors.mlir create mode 100644 mlir/test/Dialect/SCF/forall-to-for.mlir create mode 100644 mlir/test/Dialect/SparseTensor/fuse_sparse_concat_with_extract_slice.mlir create mode 100644 mlir/test/Dialect/SparseTensor/fuse_sparse_convert_into_producer.mlir delete mode 100644 mlir/test/Dialect/SparseTensor/no_fold_into_consumer.mlir create mode 100644 mlir/test/Examples/NVGPU/Ch0.py create mode 100644 mlir/test/Examples/NVGPU/Ch1.py create mode 100644 mlir/test/Examples/NVGPU/Ch2.py create mode 100644 mlir/test/Examples/NVGPU/Ch3.py create mode 100644 mlir/test/Examples/NVGPU/Ch4.py create mode 100644 mlir/test/Examples/NVGPU/Ch5.py create mode 100644 mlir/test/Examples/NVGPU/lit.local.cfg create mode 100644 mlir/test/Examples/NVGPU/tools/lit.local.cfg create mode 100644 mlir/test/Examples/NVGPU/tools/nvdsl.py create mode 100644 mlir/test/Examples/NVGPU/tools/nvgpucompiler.py create mode 100644 mlir/test/Integration/Dialect/Linalg/CPU/runtime-verification.mlir create mode 100644 mlir/test/Target/Cpp/global.mlir create mode 100644 mlir/test/mlir-tblgen/shard-op-defs.td create mode 100644 mlir/tools/mlir-src-sharder/CMakeLists.txt create mode 100644 mlir/tools/mlir-src-sharder/mlir-src-sharder.cpp create mode 100644 mlir/unittests/Tools/CMakeLists.txt create mode 100644 mlir/unittests/Tools/lsp-server-support/CMakeLists.txt create mode 100644 mlir/unittests/Tools/lsp-server-support/Transport.cpp create mode 100644 offload/include/Shared/Targets.def.in create mode 100644 utils/bazel/llvm-project-overlay/libc/libc_configure_options.bzl diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 81e9246de9b5..78a9cb77ff7d 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -91,7 +91,7 @@ function add-dependencies() { echo "${project}" case ${project} in bolt) - for p in lld llvm; do + for p in clang lld llvm; do echo $p done ;; diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index b347c443da67..b00a4b984a1d 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -48,7 +48,6 @@ cmake -S "${MONOREPO_ROOT}"/llvm -B "${BUILD_DIR}" \ -D LLVM_LIT_ARGS="-v --xunit-xml-output ${BUILD_DIR}/test-results.xml --timeout=1200 --time-tests" \ -D LLVM_ENABLE_LLD=ON \ -D CMAKE_CXX_FLAGS=-gmlt \ - -D BOLT_CLANG_EXE=/usr/bin/clang \ -D LLVM_CCACHE_BUILD=ON \ -D MLIR_ENABLE_BINDINGS_PYTHON=ON diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 45da8af51bb9..0f178df1d18f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -35,6 +35,10 @@ clang/lib/AST/Interp/ @tbaederr clang/test/AST/Interp/ @tbaederr +/clang/include/clang/CIR @lanza @bcardosolopes +/clang/lib/CIR @lanza @bcardosolopes +/clang/tools/cir-* @lanza @bcardosolopes + /lldb/ @JDevlieghere # MLIR Interfaces. diff --git a/.github/new-prs-labeler.yml b/.github/new-prs-labeler.yml index 9cf64417d3cb..d608ea449f1d 100644 --- a/.github/new-prs-labeler.yml +++ b/.github/new-prs-labeler.yml @@ -1,3 +1,6 @@ +BOLT: + - bolt/**/* + ClangIR: - clang/include/clang/CIR/**/* - clang/lib/CIR/**/* @@ -467,6 +470,7 @@ backend:m68k: libc++: - libcxx/** + - .github/workflows/libcxx-* libc++abi: - libcxxabi/** diff --git a/.github/workflows/libcxx-build-and-test.yaml b/.github/workflows/libcxx-build-and-test.yaml index 1e9367732e59..44a3d79c72c0 100644 --- a/.github/workflows/libcxx-build-and-test.yaml +++ b/.github/workflows/libcxx-build-and-test.yaml @@ -61,12 +61,10 @@ jobs: ] cc: [ 'clang-19' ] cxx: [ 'clang++-19' ] - clang_tidy: [ 'ON' ] include: - config: 'generic-gcc' cc: 'gcc-13' cxx: 'g++-13' - clang_tidy: 'OFF' steps: - uses: actions/checkout@v4 - name: ${{ matrix.config }}.${{ matrix.cxx }} @@ -74,7 +72,6 @@ jobs: env: CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} - ENABLE_CLANG_TIDY: ${{ matrix.clang_tidy }} - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 if: always() with: @@ -102,20 +99,16 @@ jobs: ] cc: [ 'clang-19' ] cxx: [ 'clang++-19' ] - clang_tidy: [ 'ON' ] include: - config: 'generic-gcc-cxx11' cc: 'gcc-13' cxx: 'g++-13' - clang_tidy: 'OFF' - config: 'generic-cxx23' cc: 'clang-17' cxx: 'clang++-17' - clang_tidy: 'OFF' - config: 'generic-cxx26' cc: 'clang-18' cxx: 'clang++-18' - clang_tidy: 'ON' steps: - uses: actions/checkout@v4 - name: ${{ matrix.config }} @@ -123,7 +116,6 @@ jobs: env: CC: ${{ matrix.cc }} CXX: ${{ matrix.cxx }} - ENABLE_CLANG_TIDY: ${{ matrix.clang_tidy }} - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 if: always() # Upload artifacts even if the build or test suite fails with: @@ -188,7 +180,6 @@ jobs: env: CC: clang-19 CXX: clang++-19 - ENABLE_CLANG_TIDY: "OFF" - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 if: always() with: diff --git a/bolt/include/bolt/Passes/BinaryPasses.h b/bolt/include/bolt/Passes/BinaryPasses.h index 8d89ef8b5484..5d7692559eda 100644 --- a/bolt/include/bolt/Passes/BinaryPasses.h +++ b/bolt/include/bolt/Passes/BinaryPasses.h @@ -400,8 +400,7 @@ public: /// dyno stats categories. class PrintProgramStats : public BinaryFunctionPass { public: - explicit PrintProgramStats(const cl::opt &PrintPass) - : BinaryFunctionPass(PrintPass) {} + explicit PrintProgramStats() : BinaryFunctionPass(false) {} const char *getName() const override { return "print-stats"; } bool shouldPrint(const BinaryFunction &) const override { return false; } diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index af832b4c7c84..f4bffba96b1d 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -424,8 +424,12 @@ private: /// Common section names. static StringRef getEHFrameSectionName() { return ".eh_frame"; } + static StringRef getEHFrameHdrSectionName() { return ".eh_frame_hdr"; } static StringRef getRelaDynSectionName() { return ".rela.dyn"; } + /// FILE symbol name used for local fragments of global functions. + static StringRef getBOLTFileSymbolName() { return "bolt-pseudo.o"; } + /// An instance of the input binary we are processing, externally owned. llvm::object::ELFObjectFileBase *InputFile; diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp index 0b2a4e86561f..70e324cc0165 100644 --- a/bolt/lib/Profile/DataAggregator.cpp +++ b/bolt/lib/Profile/DataAggregator.cpp @@ -14,6 +14,7 @@ #include "bolt/Profile/DataAggregator.h" #include "bolt/Core/BinaryContext.h" #include "bolt/Core/BinaryFunction.h" +#include "bolt/Passes/BinaryPasses.h" #include "bolt/Profile/BoltAddressTranslation.h" #include "bolt/Profile/Heatmap.h" #include "bolt/Profile/YAMLProfileWriter.h" @@ -611,6 +612,7 @@ Error DataAggregator::readProfile(BinaryContext &BC) { if (std::error_code EC = writeBATYAML(BC, opts::SaveProfile)) report_error("cannot create output data file", EC); } + BC.logBOLTErrorsAndQuitOnFatal(PrintProgramStats().runOnFunctions(BC)); } return Error::success(); diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp index be4888ccfa56..cbb7199a53dd 100644 --- a/bolt/lib/Rewrite/BinaryPassManager.cpp +++ b/bolt/lib/Rewrite/BinaryPassManager.cpp @@ -356,7 +356,7 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) { // order they're registered. // Run this pass first to use stats for the original functions. - Manager.registerPass(std::make_unique(NeverPrint)); + Manager.registerPass(std::make_unique()); if (opts::PrintProfileStats) Manager.registerPass(std::make_unique(NeverPrint)); diff --git a/bolt/lib/Rewrite/BoltDiff.cpp b/bolt/lib/Rewrite/BoltDiff.cpp index fa43b7a2f92c..74b5ca18abce 100644 --- a/bolt/lib/Rewrite/BoltDiff.cpp +++ b/bolt/lib/Rewrite/BoltDiff.cpp @@ -292,7 +292,7 @@ class RewriteInstanceDiff { } } } - PrintProgramStats PPS(opts::NeverPrint); + PrintProgramStats PPS; outs() << "* BOLT-DIFF: Starting print program stats pass for binary 1\n"; RI1.BC->logBOLTErrorsAndQuitOnFatal(PPS.runOnFunctions(*RI1.BC)); outs() << "* BOLT-DIFF: Starting print program stats pass for binary 2\n"; diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 4e0096cf988a..065260936e70 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1725,12 +1725,6 @@ void RewriteInstance::adjustFunctionBoundaries() { if (!Function.isSymbolValidInScope(Symbol, SymbolSize)) break; - // Ignore unnamed symbols. Used, for example, by debugging info on RISC-V. - if (BC->isRISCV() && cantFail(Symbol.getName()).empty()) { - ++NextSymRefI; - continue; - } - // Skip basic block labels. This happens on RISC-V with linker relaxation // enabled because every branch needs a relocation and corresponding // symbol. We don't want to add such symbols as entry points. @@ -3932,11 +3926,6 @@ void RewriteInstance::patchELFPHDRTable() { OS.seek(PHDRTableOffset); - bool ModdedGnuStack = false; - (void)ModdedGnuStack; - bool AddedSegment = false; - (void)AddedSegment; - auto createNewTextPhdr = [&]() { ELF64LEPhdrTy NewPhdr; NewPhdr.p_type = ELF::PT_LOAD; @@ -3952,40 +3941,53 @@ void RewriteInstance::patchELFPHDRTable() { NewPhdr.p_filesz = NewTextSegmentSize; NewPhdr.p_memsz = NewTextSegmentSize; NewPhdr.p_flags = ELF::PF_X | ELF::PF_R; - // FIXME: Currently instrumentation is experimental and the runtime data - // is emitted with code, thus everything needs to be writable - if (opts::Instrument) + if (opts::Instrument) { + // FIXME: Currently instrumentation is experimental and the runtime data + // is emitted with code, thus everything needs to be writable. NewPhdr.p_flags |= ELF::PF_W; + } NewPhdr.p_align = BC->PageAlign; return NewPhdr; }; - auto createNewWritableSectionsPhdr = [&]() { - ELF64LEPhdrTy NewPhdr; - NewPhdr.p_type = ELF::PT_LOAD; - NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress); - NewPhdr.p_vaddr = NewWritableSegmentAddress; - NewPhdr.p_paddr = NewWritableSegmentAddress; - NewPhdr.p_filesz = NewWritableSegmentSize; - NewPhdr.p_memsz = NewWritableSegmentSize; - NewPhdr.p_align = BC->RegularPageSize; - NewPhdr.p_flags = ELF::PF_R | ELF::PF_W; - return NewPhdr; + auto writeNewSegmentPhdrs = [&]() { + ELF64LE::Phdr NewTextPhdr = createNewTextPhdr(); + OS.write(reinterpret_cast(&NewTextPhdr), sizeof(NewTextPhdr)); + + if (NewWritableSegmentSize) { + ELF64LEPhdrTy NewPhdr; + NewPhdr.p_type = ELF::PT_LOAD; + NewPhdr.p_offset = getFileOffsetForAddress(NewWritableSegmentAddress); + NewPhdr.p_vaddr = NewWritableSegmentAddress; + NewPhdr.p_paddr = NewWritableSegmentAddress; + NewPhdr.p_filesz = NewWritableSegmentSize; + NewPhdr.p_memsz = NewWritableSegmentSize; + NewPhdr.p_align = BC->RegularPageSize; + NewPhdr.p_flags = ELF::PF_R | ELF::PF_W; + OS.write(reinterpret_cast(&NewPhdr), sizeof(NewPhdr)); + } }; + bool ModdedGnuStack = false; + bool AddedSegment = false; + // Copy existing program headers with modifications. for (const ELF64LE::Phdr &Phdr : cantFail(Obj.program_headers())) { ELF64LE::Phdr NewPhdr = Phdr; - if (PHDRTableAddress && Phdr.p_type == ELF::PT_PHDR) { - NewPhdr.p_offset = PHDRTableOffset; - NewPhdr.p_vaddr = PHDRTableAddress; - NewPhdr.p_paddr = PHDRTableAddress; - NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum; - NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum; - } else if (Phdr.p_type == ELF::PT_GNU_EH_FRAME) { - ErrorOr EHFrameHdrSec = - BC->getUniqueSectionByName(getNewSecPrefix() + ".eh_frame_hdr"); + switch (Phdr.p_type) { + case ELF::PT_PHDR: + if (PHDRTableAddress) { + NewPhdr.p_offset = PHDRTableOffset; + NewPhdr.p_vaddr = PHDRTableAddress; + NewPhdr.p_paddr = PHDRTableAddress; + NewPhdr.p_filesz = sizeof(NewPhdr) * Phnum; + NewPhdr.p_memsz = sizeof(NewPhdr) * Phnum; + } + break; + case ELF::PT_GNU_EH_FRAME: { + ErrorOr EHFrameHdrSec = BC->getUniqueSectionByName( + getNewSecPrefix() + getEHFrameHdrSectionName()); if (EHFrameHdrSec && EHFrameHdrSec->isAllocatable() && EHFrameHdrSec->isFinalized()) { NewPhdr.p_offset = EHFrameHdrSec->getOutputFileOffset(); @@ -3994,37 +3996,36 @@ void RewriteInstance::patchELFPHDRTable() { NewPhdr.p_filesz = EHFrameHdrSec->getOutputSize(); NewPhdr.p_memsz = EHFrameHdrSec->getOutputSize(); } - } else if (opts::UseGnuStack && Phdr.p_type == ELF::PT_GNU_STACK) { - NewPhdr = createNewTextPhdr(); - ModdedGnuStack = true; - } else if (!opts::UseGnuStack && Phdr.p_type == ELF::PT_DYNAMIC) { - // Insert the new header before DYNAMIC. - ELF64LE::Phdr NewTextPhdr = createNewTextPhdr(); - OS.write(reinterpret_cast(&NewTextPhdr), - sizeof(NewTextPhdr)); - if (NewWritableSegmentSize) { - ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr(); - OS.write(reinterpret_cast(&NewWritablePhdr), - sizeof(NewWritablePhdr)); + break; + } + case ELF::PT_GNU_STACK: + if (opts::UseGnuStack) { + // Overwrite the header with the new text segment header. + NewPhdr = createNewTextPhdr(); + ModdedGnuStack = true; } - AddedSegment = true; + break; + case ELF::PT_DYNAMIC: + if (!opts::UseGnuStack) { + // Insert new headers before DYNAMIC. + writeNewSegmentPhdrs(); + AddedSegment = true; + } + break; } OS.write(reinterpret_cast(&NewPhdr), sizeof(NewPhdr)); } if (!opts::UseGnuStack && !AddedSegment) { - // Append the new header to the end of the table. - ELF64LE::Phdr NewTextPhdr = createNewTextPhdr(); - OS.write(reinterpret_cast(&NewTextPhdr), sizeof(NewTextPhdr)); - if (NewWritableSegmentSize) { - ELF64LEPhdrTy NewWritablePhdr = createNewWritableSectionsPhdr(); - OS.write(reinterpret_cast(&NewWritablePhdr), - sizeof(NewWritablePhdr)); - } + // Append new headers to the end of the table. + writeNewSegmentPhdrs(); } - assert((!opts::UseGnuStack || ModdedGnuStack) && - "could not find GNU_STACK program header to modify"); + if (opts::UseGnuStack && !ModdedGnuStack) { + BC->errs() + << "BOLT-ERROR: could not find PT_GNU_STACK program header to modify\n"; + exit(1); + } } namespace { @@ -4493,6 +4494,8 @@ void RewriteInstance::updateELFSymbolTable( // Symbols for the new symbol table. std::vector Symbols; + bool EmittedColdFileSymbol = false; + auto getNewSectionIndex = [&](uint32_t OldIndex) { // For dynamic symbol table, the section index could be wrong on the input, // and its value is ignored by the runtime if it's different from @@ -4551,6 +4554,20 @@ void RewriteInstance::updateELFSymbolTable( Symbols.emplace_back(ICFSymbol); } if (Function.isSplit()) { + // Prepend synthetic FILE symbol to prevent local cold fragments from + // colliding with existing symbols with the same name. + if (!EmittedColdFileSymbol && + FunctionSymbol.getBinding() == ELF::STB_GLOBAL) { + ELFSymTy FileSymbol; + FileSymbol.st_shndx = ELF::SHN_ABS; + FileSymbol.st_name = AddToStrTab(getBOLTFileSymbolName()); + FileSymbol.st_value = 0; + FileSymbol.st_size = 0; + FileSymbol.st_other = 0; + FileSymbol.setBindingAndType(ELF::STB_LOCAL, ELF::STT_FILE); + Symbols.emplace_back(FileSymbol); + EmittedColdFileSymbol = true; + } for (const FunctionFragment &FF : Function.getLayout().getSplitFragments()) { if (FF.getAddress()) { @@ -5432,6 +5449,17 @@ uint64_t RewriteInstance::getNewFunctionOrDataAddress(uint64_t OldAddress) { if (BD && BD->isMoved()) return BD->getOutputAddress(); + if (const BinaryFunction *BF = + BC->getBinaryFunctionContainingAddress(OldAddress)) { + if (BF->isEmitted()) { + BC->errs() << "BOLT-ERROR: unable to get new address corresponding to " + "input address 0x" + << Twine::utohexstr(OldAddress) << " in function " << *BF + << ". Consider adding this function to --skip-funcs=...\n"; + exit(1); + } + } + return 0; } @@ -5671,7 +5699,8 @@ void RewriteInstance::writeEHFrameHeader() { BC->AsmInfo->getCodePointerSize())); check_error(std::move(Er), "failed to parse EH frame"); - LLVM_DEBUG(dbgs() << "BOLT: writing a new .eh_frame_hdr\n"); + LLVM_DEBUG(dbgs() << "BOLT: writing a new " << getEHFrameHdrSectionName() + << '\n'); NextAvailableAddress = appendPadding(Out->os(), NextAvailableAddress, EHFrameHdrAlign); @@ -5689,16 +5718,17 @@ void RewriteInstance::writeEHFrameHeader() { const unsigned Flags = BinarySection::getFlags(/*IsReadOnly=*/true, /*IsText=*/false, /*IsAllocatable=*/true); - BinarySection *OldEHFrameHdrSection = getSection(".eh_frame_hdr"); + BinarySection *OldEHFrameHdrSection = getSection(getEHFrameHdrSectionName()); if (OldEHFrameHdrSection) - OldEHFrameHdrSection->setOutputName(getOrgSecPrefix() + ".eh_frame_hdr"); + OldEHFrameHdrSection->setOutputName(getOrgSecPrefix() + + getEHFrameHdrSectionName()); BinarySection &EHFrameHdrSec = BC->registerOrUpdateSection( - getNewSecPrefix() + ".eh_frame_hdr", ELF::SHT_PROGBITS, Flags, nullptr, - NewEHFrameHdr.size(), /*Alignment=*/1); + getNewSecPrefix() + getEHFrameHdrSectionName(), ELF::SHT_PROGBITS, Flags, + nullptr, NewEHFrameHdr.size(), /*Alignment=*/1); EHFrameHdrSec.setOutputFileOffset(EHFrameHdrFileOffset); EHFrameHdrSec.setOutputAddress(EHFrameHdrOutputAddress); - EHFrameHdrSec.setOutputName(".eh_frame_hdr"); + EHFrameHdrSec.setOutputName(getEHFrameHdrSectionName()); NextAvailableAddress += EHFrameHdrSec.getOutputSize(); diff --git a/bolt/test/RISCV/unnamed-sym-no-entry.c b/bolt/test/RISCV/fake-label-no-entry.c similarity index 85% rename from bolt/test/RISCV/unnamed-sym-no-entry.c rename to bolt/test/RISCV/fake-label-no-entry.c index 605bbc00aeec..bd125263101b 100644 --- a/bolt/test/RISCV/unnamed-sym-no-entry.c +++ b/bolt/test/RISCV/fake-label-no-entry.c @@ -5,12 +5,12 @@ // RUN: %clang %cflags -g -Wl,-q -o %t %s -/// Verify that the binary indeed contains an unnamed symbol at _start +/// Verify that the binary indeed contains a fake label ".L0 " at _start. // RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=CHECK-ELF // CHECK-ELF-DAG: [[#%x,START:]] {{.*}} FUNC GLOBAL DEFAULT [[#%d,SECTION:]] _start{{$}} -// CHECK-ELF-DAG: [[#%x,START]] {{.*}} NOTYPE LOCAL DEFAULT [[#SECTION]] {{$}} +// CHECK-ELF-DAG: [[#%x,START]] {{.*}} NOTYPE LOCAL DEFAULT [[#SECTION]] .L0 {{$}} -/// Verify that BOLT did not create an extra entry point for the unnamed symbol +/// Verify that BOLT did not create an extra entry point for the fake label. // RUN: llvm-bolt -o %t.bolt %t --print-cfg | FileCheck %s // CHECK: Binary Function "_start" after building cfg { // CHECK: IsMultiEntry: 0 diff --git a/bolt/test/X86/cdsplit-symbol-names.s b/bolt/test/X86/cdsplit-symbol-names.s index e2259276e255..e53863e22246 100644 --- a/bolt/test/X86/cdsplit-symbol-names.s +++ b/bolt/test/X86/cdsplit-symbol-names.s @@ -10,6 +10,7 @@ # RUN: --call-scale=2 --data=%t.fdata --reorder-blocks=ext-tsp # RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS-WARM +# CHECK-SYMS-WARM: 0000000000000000 l df *ABS* 0000000000000000 bolt-pseudo.o # CHECK-SYMS-WARM: .text.warm # CHECK-SYMS-WARM-SAME: chain.warm # CHECK-SYMS-WARM: .text.cold diff --git a/bolt/test/X86/indirect-goto-pie.test b/bolt/test/X86/indirect-goto-pie.test new file mode 100644 index 000000000000..039ff5c41d3d --- /dev/null +++ b/bolt/test/X86/indirect-goto-pie.test @@ -0,0 +1,16 @@ +# Check that llvm-bolt fails to process PIC binaries with computed goto, as the +# support is not there yet for correctly updating dynamic relocations +# referencing code inside functions. + +REQUIRES: x86_64-linux + +RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q +RUN: not llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \ +RUN: |& FileCheck %s + +# Check that processing works if main() is skipped. +RUN: llvm-bolt %t -o %t.bolt --relocs=1 --skip-funcs=main + +CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW + +CHECK: BOLT-ERROR: unable to get new address diff --git a/bolt/test/X86/pre-aggregated-perf.test b/bolt/test/X86/pre-aggregated-perf.test index e8c3f64239a2..0bd44720f1b7 100644 --- a/bolt/test/X86/pre-aggregated-perf.test +++ b/bolt/test/X86/pre-aggregated-perf.test @@ -11,7 +11,14 @@ REQUIRES: system-linux RUN: yaml2obj %p/Inputs/blarge.yaml &> %t.exe RUN: perf2bolt %t.exe -o %t --pa -p %p/Inputs/pre-aggregated.txt -w %t.new \ -RUN: --profile-use-dfs +RUN: --profile-use-dfs | FileCheck %s + +RUN: llvm-bolt %t.exe -data %t -o %t.null | FileCheck %s +RUN: llvm-bolt %t.exe -data %t.new -o %t.null | FileCheck %s +RUN: llvm-bolt %t.exe -p %p/Inputs/pre-aggregated.txt --pa -o %t.null | FileCheck %s + +CHECK: BOLT-INFO: 4 out of 7 functions in the binary (57.1%) have non-empty execution profile + RUN: cat %t | sort | FileCheck %s -check-prefix=PERF2BOLT RUN: cat %t.new | FileCheck %s -check-prefix=NEWFORMAT diff --git a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s index a57131131423..3fdd5f5e38fe 100644 --- a/bolt/test/X86/shrinkwrapping-do-not-pessimize.s +++ b/bolt/test/X86/shrinkwrapping-do-not-pessimize.s @@ -53,6 +53,6 @@ end_if_1: .size _start, .-_start .data -rel: .quad end_if_1 +rel: .quad _start # CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 0 spills inserting push/pops diff --git a/bolt/test/runtime/X86/Inputs/indirect_goto.c b/bolt/test/runtime/X86/Inputs/indirect_goto.c deleted file mode 100644 index b781e9e03b6d..000000000000 --- a/bolt/test/runtime/X86/Inputs/indirect_goto.c +++ /dev/null @@ -1,18 +0,0 @@ -int main(int argc, char *argv[]) { - static const void *T1[] = { &&L1, &&L2 }; - static const void *T2[] = { &&L2, &&L3 }; - - const void **T = (argc > 1) ? T1 : T2; - - int i = 0; - -L0: - goto *T[argc]; -L1: - ++i; -L2: - i++; -L3: - i++; - return i; -} diff --git a/bolt/test/runtime/X86/indirect-goto-pie.test b/bolt/test/runtime/X86/indirect-goto-pie.test deleted file mode 100644 index 76089fda3abf..000000000000 --- a/bolt/test/runtime/X86/indirect-goto-pie.test +++ /dev/null @@ -1,10 +0,0 @@ -# Check llvm-bolt processes binaries compiled from sources that use indirect goto. -REQUIRES: x86_64-linux - -RUN: %clang %S/Inputs/indirect_goto.c -o %t -fpic -pie -Wl,-q -RUN: llvm-bolt %t -o %t.bolt --relocs=1 --print-cfg --print-only=main \ -RUN: |& FileCheck %s -# The test fails as we don't update corresponding dynamic relocations. -RUN: not %t.bolt - -CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp index 3e926236adb4..710b361e16c0 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.cpp @@ -139,6 +139,12 @@ void ClangTidyCheck::OptionsView::storeInt(ClangTidyOptions::OptionMap &Options, store(Options, LocalName, llvm::itostr(Value)); } +void ClangTidyCheck::OptionsView::storeUnsigned( + ClangTidyOptions::OptionMap &Options, StringRef LocalName, + uint64_t Value) const { + store(Options, LocalName, llvm::utostr(Value)); +} + template <> void ClangTidyCheck::OptionsView::store( ClangTidyOptions::OptionMap &Options, StringRef LocalName, diff --git a/clang-tools-extra/clang-tidy/ClangTidyCheck.h b/clang-tools-extra/clang-tidy/ClangTidyCheck.h index 656a2f008f6e..7427aa9bf48f 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyCheck.h +++ b/clang-tools-extra/clang-tidy/ClangTidyCheck.h @@ -411,7 +411,10 @@ public: std::enable_if_t> store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, T Value) const { - storeInt(Options, LocalName, Value); + if constexpr (std::is_signed_v) + storeInt(Options, LocalName, Value); + else + storeUnsigned(Options, LocalName, Value); } /// Stores an option with the check-local name \p LocalName with @@ -422,7 +425,7 @@ public: store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, std::optional Value) const { if (Value) - storeInt(Options, LocalName, *Value); + store(Options, LocalName, *Value); else store(Options, LocalName, "none"); } @@ -470,6 +473,8 @@ public: void storeInt(ClangTidyOptions::OptionMap &Options, StringRef LocalName, int64_t Value) const; + void storeUnsigned(ClangTidyOptions::OptionMap &Options, + StringRef LocalName, uint64_t Value) const; std::string NamePrefix; const ClangTidyOptions::OptionMap &CheckOptions; diff --git a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp index 2931325d8b57..1b92d2e60cc1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -54,6 +54,7 @@ #include "PosixReturnCheck.h" #include "RedundantBranchConditionCheck.h" #include "ReservedIdentifierCheck.h" +#include "ReturnConstRefFromParameterCheck.h" #include "SharedPtrArrayMismatchCheck.h" #include "SignalHandlerCheck.h" #include "SignedCharMisuseCheck.h" @@ -137,6 +138,8 @@ public: "bugprone-inaccurate-erase"); CheckFactories.registerCheck( "bugprone-incorrect-enable-if"); + CheckFactories.registerCheck( + "bugprone-return-const-ref-from-parameter"); CheckFactories.registerCheck( "bugprone-switch-missing-default-case"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index 081ba67efe15..2d303191f886 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -26,6 +26,7 @@ add_clang_library(clangTidyBugproneModule ImplicitWideningOfMultiplicationResultCheck.cpp InaccurateEraseCheck.cpp IncorrectEnableIfCheck.cpp + ReturnConstRefFromParameterCheck.cpp SuspiciousStringviewDataUsageCheck.cpp SwitchMissingDefaultCaseCheck.cpp IncDecInConditionsCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp index 84e99c7fafc7..10868129e76d 100644 --- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp @@ -967,7 +967,8 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, // Get out the qualifiers of the original type. This will always be // re-applied to the WorkType to ensure it is the same qualification as the // original From was. - auto QualifiersToApply = From.split().Quals.getAsOpaqueValue(); + auto FastQualifiersToApply = static_cast( + From.split().Quals.getAsOpaqueValue() & Qualifiers::FastMask); // LValue->RValue is irrelevant for the check, because it is a thing to be // done at a call site, and will be performed if need be performed. @@ -993,7 +994,7 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, // "const double -> double". LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Conversion between numerics.\n"); - WorkType = QualType{ToBuiltin, QualifiersToApply}; + WorkType = QualType{ToBuiltin, FastQualifiersToApply}; } const auto *FromEnum = WorkType->getAs(); @@ -1002,7 +1003,7 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, // Unscoped enumerations (or enumerations in C) convert to numerics. LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Unscoped enum to numeric.\n"); - WorkType = QualType{ToBuiltin, QualifiersToApply}; + WorkType = QualType{ToBuiltin, FastQualifiersToApply}; } else if (FromNumeric && ToEnum && ToEnum->isUnscopedEnumerationType()) { // Numeric types convert to enumerations only in C. if (Ctx.getLangOpts().CPlusPlus) { @@ -1013,7 +1014,7 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Numeric to unscoped enum.\n"); - WorkType = QualType{ToEnum, QualifiersToApply}; + WorkType = QualType{ToEnum, FastQualifiersToApply}; } // Check for pointer conversions. @@ -1022,14 +1023,14 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, if (FromPtr && ToPtr) { if (ToPtr->isVoidPointerType()) { LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. To void pointer.\n"); - WorkType = QualType{ToPtr, QualifiersToApply}; + WorkType = QualType{ToPtr, FastQualifiersToApply}; } const auto *FromRecordPtr = FromPtr->getPointeeCXXRecordDecl(); const auto *ToRecordPtr = ToPtr->getPointeeCXXRecordDecl(); if (isDerivedToBase(FromRecordPtr, ToRecordPtr)) { LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived* to Base*\n"); - WorkType = QualType{ToPtr, QualifiersToApply}; + WorkType = QualType{ToPtr, FastQualifiersToApply}; } } @@ -1039,7 +1040,7 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, const auto *ToRecord = To->getAsCXXRecordDecl(); if (isDerivedToBase(FromRecord, ToRecord)) { LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n"); - WorkType = QualType{ToRecord->getTypeForDecl(), QualifiersToApply}; + WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply}; } if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) { @@ -1054,7 +1055,7 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From, !ToFunctionPtr->hasNoexceptExceptionSpec()) { LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. noexcept function " "pointer to non-noexcept.\n"); - WorkType = QualType{ToPtr, QualifiersToApply}; + WorkType = QualType{ToPtr, FastQualifiersToApply}; } } diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp new file mode 100644 index 000000000000..8ae37d4f774d --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp @@ -0,0 +1,34 @@ +//===--- ReturnConstRefFromParameterCheck.cpp - clang-tidy ----------------===// +// +// Part of the LLVM Project, under the Apache 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 "ReturnConstRefFromParameterCheck.h" +#include "../utils/Matchers.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + returnStmt(hasReturnValue(declRefExpr(to(parmVarDecl(hasType( + hasCanonicalType(matchers::isReferenceToConst()))))))) + .bind("ret"), + this); +} + +void ReturnConstRefFromParameterCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *R = Result.Nodes.getNodeAs("ret"); + diag(R->getRetValue()->getBeginLoc(), + "returning a constant reference parameter may cause a use-after-free " + "when the parameter is constructed from a temporary"); +} + +} // namespace clang::tidy::bugprone diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.h b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.h new file mode 100644 index 000000000000..8768d0708738 --- /dev/null +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.h @@ -0,0 +1,40 @@ +//===--- ReturnConstRefFromParameterCheck.h - clang-tidy --------*- 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_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RETURNCONSTREFFROMPARAMETERCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RETURNCONSTREFFROMPARAMETERCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::bugprone { + +/// Detects return statements that return a constant reference parameter as +/// constant reference. This may cause use-after-free errors if the caller uses +/// xvalues as arguments. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/bugprone/return-const-ref-from-parameter.html +class ReturnConstRefFromParameterCheck : public ClangTidyCheck { +public: + ReturnConstRefFromParameterCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional getCheckTraversalKind() const override { + // Use 'AsIs' to make sure the return type is exactly the same as the + // parameter type. + return TK_AsIs; + } + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus; + } +}; + +} // namespace clang::tidy::bugprone + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_RETURNCONSTREFFROMPARAMETERCHECK_H diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index 6852db6c2ee3..8005d6e91c06 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -16,6 +16,7 @@ add_clang_library(clangTidyModernizeModule MakeSharedCheck.cpp MakeSmartPtrCheck.cpp MakeUniqueCheck.cpp + MinMaxUseInitializerListCheck.cpp ModernizeTidyModule.cpp PassByValueCheck.cpp RawStringLiteralCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp new file mode 100644 index 000000000000..45f7700463d5 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.cpp @@ -0,0 +1,271 @@ +//===--- MinMaxUseInitializerListCheck.cpp - clang-tidy -------------------===// +// +// Part of the LLVM Project, under the Apache 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 "MinMaxUseInitializerListCheck.h" +#include "../utils/ASTUtils.h" +#include "../utils/LexerUtils.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/Lexer.h" + +using namespace clang; + +namespace { + +struct FindArgsResult { + const Expr *First; + const Expr *Last; + const Expr *Compare; + SmallVector Args; +}; + +} // anonymous namespace + +using namespace clang::ast_matchers; + +namespace clang::tidy::modernize { + +static FindArgsResult findArgs(const CallExpr *Call) { + FindArgsResult Result; + Result.First = nullptr; + Result.Last = nullptr; + Result.Compare = nullptr; + + // check if the function has initializer list argument + if (Call->getNumArgs() < 3) { + auto ArgIterator = Call->arguments().begin(); + + const auto *InitListExpr = + dyn_cast(*ArgIterator); + const auto *InitList = + InitListExpr != nullptr + ? dyn_cast( + InitListExpr->getSubExpr()->IgnoreImplicit()) + : nullptr; + + if (InitList) { + Result.Args.append(InitList->inits().begin(), InitList->inits().end()); + Result.First = *ArgIterator; + Result.Last = *ArgIterator; + + // check if there is a comparison argument + std::advance(ArgIterator, 1); + if (ArgIterator != Call->arguments().end()) + Result.Compare = *ArgIterator; + + return Result; + } + Result.Args = SmallVector(Call->arguments()); + } else { + // if it has 3 arguments then the last will be the comparison + Result.Compare = *(std::next(Call->arguments().begin(), 2)); + Result.Args = SmallVector(llvm::drop_end(Call->arguments())); + } + Result.First = Result.Args.front(); + Result.Last = Result.Args.back(); + + return Result; +} + +static SmallVector +generateReplacements(const MatchFinder::MatchResult &Match, + const CallExpr *TopCall, const FindArgsResult &Result, + const bool IgnoreNonTrivialTypes, + const std::uint64_t IgnoreTrivialTypesOfSizeAbove) { + SmallVector FixItHints; + const SourceManager &SourceMngr = *Match.SourceManager; + const LangOptions &LanguageOpts = Match.Context->getLangOpts(); + + const QualType ResultType = TopCall->getDirectCallee() + ->getReturnType() + .getCanonicalType() + .getNonReferenceType() + .getUnqualifiedType(); + + // check if the type is trivial + const bool IsResultTypeTrivial = ResultType.isTrivialType(*Match.Context); + + if ((!IsResultTypeTrivial && IgnoreNonTrivialTypes)) + return FixItHints; + + if (IsResultTypeTrivial && + static_cast( + Match.Context->getTypeSizeInChars(ResultType).getQuantity()) > + IgnoreTrivialTypesOfSizeAbove) + return FixItHints; + + for (const Expr *Arg : Result.Args) { + const auto *InnerCall = dyn_cast(Arg->IgnoreParenImpCasts()); + + // If the argument is not a nested call + if (!InnerCall) { + // check if typecast is required + const QualType ArgType = Arg->IgnoreParenImpCasts() + ->getType() + .getCanonicalType() + .getUnqualifiedType(); + + if (ArgType == ResultType) + continue; + + const StringRef ArgText = Lexer::getSourceText( + CharSourceRange::getTokenRange(Arg->getSourceRange()), SourceMngr, + LanguageOpts); + + const auto Replacement = Twine("static_cast<") + .concat(ResultType.getAsString(LanguageOpts)) + .concat(">(") + .concat(ArgText) + .concat(")") + .str(); + + FixItHints.push_back( + FixItHint::CreateReplacement(Arg->getSourceRange(), Replacement)); + continue; + } + + const FindArgsResult InnerResult = findArgs(InnerCall); + + // if the nested call doesn't have arguments skip it + if (!InnerResult.First || !InnerResult.Last) + continue; + + // if the nested call is not the same as the top call + if (InnerCall->getDirectCallee()->getQualifiedNameAsString() != + TopCall->getDirectCallee()->getQualifiedNameAsString()) + continue; + + // if the nested call doesn't have the same compare function + if ((Result.Compare || InnerResult.Compare) && + !utils::areStatementsIdentical(Result.Compare, InnerResult.Compare, + *Match.Context)) + continue; + + // remove the function call + FixItHints.push_back( + FixItHint::CreateRemoval(InnerCall->getCallee()->getSourceRange())); + + // remove the parentheses + const auto LParen = utils::lexer::findNextTokenSkippingComments( + InnerCall->getCallee()->getEndLoc(), SourceMngr, LanguageOpts); + if (LParen.has_value() && LParen->is(tok::l_paren)) + FixItHints.push_back( + FixItHint::CreateRemoval(SourceRange(LParen->getLocation()))); + FixItHints.push_back( + FixItHint::CreateRemoval(SourceRange(InnerCall->getRParenLoc()))); + + // if the inner call has an initializer list arg + if (InnerResult.First == InnerResult.Last) { + // remove the initializer list braces + FixItHints.push_back(FixItHint::CreateRemoval( + CharSourceRange::getTokenRange(InnerResult.First->getBeginLoc()))); + FixItHints.push_back(FixItHint::CreateRemoval( + CharSourceRange::getTokenRange(InnerResult.First->getEndLoc()))); + } + + const SmallVector InnerReplacements = generateReplacements( + Match, InnerCall, InnerResult, IgnoreNonTrivialTypes, + IgnoreTrivialTypesOfSizeAbove); + + FixItHints.append(InnerReplacements); + + if (InnerResult.Compare) { + // find the comma after the value arguments + const auto Comma = utils::lexer::findNextTokenSkippingComments( + InnerResult.Last->getEndLoc(), SourceMngr, LanguageOpts); + + // remove the comma and the comparison + if (Comma.has_value() && Comma->is(tok::comma)) + FixItHints.push_back( + FixItHint::CreateRemoval(SourceRange(Comma->getLocation()))); + + FixItHints.push_back( + FixItHint::CreateRemoval(InnerResult.Compare->getSourceRange())); + } + } + + return FixItHints; +} + +MinMaxUseInitializerListCheck::MinMaxUseInitializerListCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreNonTrivialTypes(Options.get("IgnoreNonTrivialTypes", true)), + IgnoreTrivialTypesOfSizeAbove( + Options.get("IgnoreTrivialTypesOfSizeAbove", 32L)), + Inserter(Options.getLocalOrGlobal("IncludeStyle", + utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void MinMaxUseInitializerListCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreNonTrivialTypes", IgnoreNonTrivialTypes); + Options.store(Opts, "IgnoreTrivialTypesOfSizeAbove", + IgnoreTrivialTypesOfSizeAbove); + Options.store(Opts, "IncludeStyle", Inserter.getStyle()); +} + +void MinMaxUseInitializerListCheck::registerMatchers(MatchFinder *Finder) { + auto CreateMatcher = [](const StringRef FunctionName) { + auto FuncDecl = functionDecl(hasName(FunctionName)); + auto Expression = callExpr(callee(FuncDecl)); + + return callExpr(callee(FuncDecl), + anyOf(hasArgument(0, Expression), + hasArgument(1, Expression), + hasArgument(0, cxxStdInitializerListExpr())), + unless(hasParent(Expression))) + .bind("topCall"); + }; + + Finder->addMatcher(CreateMatcher("::std::max"), this); + Finder->addMatcher(CreateMatcher("::std::min"), this); +} + +void MinMaxUseInitializerListCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + Inserter.registerPreprocessor(PP); +} + +void MinMaxUseInitializerListCheck::check( + const MatchFinder::MatchResult &Match) { + + const auto *TopCall = Match.Nodes.getNodeAs("topCall"); + + const FindArgsResult Result = findArgs(TopCall); + const SmallVector Replacements = + generateReplacements(Match, TopCall, Result, IgnoreNonTrivialTypes, + IgnoreTrivialTypesOfSizeAbove); + + if (Replacements.empty()) + return; + + const DiagnosticBuilder Diagnostic = + diag(TopCall->getBeginLoc(), + "do not use nested 'std::%0' calls, use an initializer list instead") + << TopCall->getDirectCallee()->getName() + << Inserter.createIncludeInsertion( + Match.SourceManager->getFileID(TopCall->getBeginLoc()), + ""); + + // if the top call doesn't have an initializer list argument + if (Result.First != Result.Last) { + // add { and } insertions + Diagnostic << FixItHint::CreateInsertion(Result.First->getBeginLoc(), "{"); + + Diagnostic << FixItHint::CreateInsertion( + Lexer::getLocForEndOfToken(Result.Last->getEndLoc(), 0, + *Match.SourceManager, + Match.Context->getLangOpts()), + "}"); + } + + Diagnostic << Replacements; +} + +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.h b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.h new file mode 100644 index 000000000000..577d12653076 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/MinMaxUseInitializerListCheck.h @@ -0,0 +1,56 @@ +//===--- MinMaxUseInitializerListCheck.h - clang-tidy -----------*- 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_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MINMAXUSEINITIALIZERLISTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MINMAXUSEINITIALIZERLISTCHECK_H + +#include "../ClangTidyCheck.h" +#include "../utils/IncludeInserter.h" + +namespace clang::tidy::modernize { + +/// Replaces nested ``std::min`` and ``std::max`` calls with an initializer list +/// where applicable. +/// +/// For example: +/// +/// \code +/// int a = std::max(std::max(i, j), k); +/// \endcode +/// +/// This code is transformed to: +/// +/// \code +/// int a = std::max({i, j, k}); +/// \endcode +class MinMaxUseInitializerListCheck : public ClangTidyCheck { +public: + MinMaxUseInitializerListCheck(StringRef Name, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) override; + void check(const ast_matchers::MatchFinder::MatchResult &Match) override; + + bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { + return LangOpts.CPlusPlus11; + } + std::optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } + +private: + bool IgnoreNonTrivialTypes; + std::uint64_t IgnoreTrivialTypesOfSizeAbove; + utils::IncludeInserter Inserter; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_MINMAXUSEINITIALIZERLISTCHECK_H diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index e96cf274f58c..776558433c5b 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -18,6 +18,7 @@ #include "MacroToEnumCheck.h" #include "MakeSharedCheck.h" #include "MakeUniqueCheck.h" +#include "MinMaxUseInitializerListCheck.h" #include "PassByValueCheck.h" #include "RawStringLiteralCheck.h" #include "RedundantVoidArgCheck.h" @@ -68,6 +69,8 @@ public: CheckFactories.registerCheck("modernize-macro-to-enum"); CheckFactories.registerCheck("modernize-make-shared"); CheckFactories.registerCheck("modernize-make-unique"); + CheckFactories.registerCheck( + "modernize-min-max-use-initializer-list"); CheckFactories.registerCheck("modernize-pass-by-value"); CheckFactories.registerCheck( "modernize-use-designated-initializers"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h index 6c32a4edb4ff..f1591bae4465 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseNullptrCheck.h @@ -19,7 +19,7 @@ public: bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { // FIXME this should be CPlusPlus11 but that causes test cases to // erroneously fail. - return LangOpts.CPlusPlus; + return LangOpts.CPlusPlus || LangOpts.C23; } void storeOptions(ClangTidyOptions::OptionMap &Opts) override; void registerMatchers(ast_matchers::MatchFinder *Finder) override; diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp index 062f6e9911db..89ee45faecd7 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.cpp @@ -43,7 +43,9 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(hasName("find")).bind("find_fun")), // ... on a class with a starts_with function. on(hasType( - hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction))))); + hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction)))), + // Bind search expression. + hasArgument(0, expr().bind("search_expr"))); const auto RFindExpr = cxxMemberCallExpr( // A method call with a second argument of zero... @@ -52,15 +54,68 @@ void UseStartsEndsWithCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(hasName("rfind")).bind("find_fun")), // ... on a class with a starts_with function. on(hasType( - hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction))))); + hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction)))), + // Bind search expression. + hasArgument(0, expr().bind("search_expr"))); + + // Match a string literal and an integer or strlen() call matching the length. + const auto HasStringLiteralAndLengthArgs = [](const auto StringArgIndex, + const auto LengthArgIndex) { + return allOf( + hasArgument(StringArgIndex, stringLiteral().bind("string_literal_arg")), + hasArgument(LengthArgIndex, + anyOf(integerLiteral().bind("integer_literal_size_arg"), + callExpr(callee(functionDecl(parameterCountIs(1), + hasName("strlen"))), + hasArgument(0, stringLiteral().bind( + "strlen_arg")))))); + }; + + // Match a string variable and a call to length() or size(). + const auto HasStringVariableAndSizeCallArgs = [](const auto StringArgIndex, + const auto LengthArgIndex) { + return allOf( + hasArgument(StringArgIndex, declRefExpr(hasDeclaration( + decl().bind("string_var_decl")))), + hasArgument(LengthArgIndex, + cxxMemberCallExpr( + callee(cxxMethodDecl(isConst(), parameterCountIs(0), + hasAnyName("size", "length"))), + on(declRefExpr( + to(decl(equalsBoundNode("string_var_decl")))))))); + }; - const auto FindOrRFindExpr = - cxxMemberCallExpr(anyOf(FindExpr, RFindExpr)).bind("find_expr"); + // Match either one of the two cases above. + const auto HasStringAndLengthArgs = + [HasStringLiteralAndLengthArgs, HasStringVariableAndSizeCallArgs]( + const auto StringArgIndex, const auto LengthArgIndex) { + return anyOf( + HasStringLiteralAndLengthArgs(StringArgIndex, LengthArgIndex), + HasStringVariableAndSizeCallArgs(StringArgIndex, LengthArgIndex)); + }; + + const auto CompareExpr = cxxMemberCallExpr( + // A method call with three arguments... + argumentCountIs(3), + // ... where the first argument is zero... + hasArgument(0, ZeroLiteral), + // ... named compare... + callee(cxxMethodDecl(hasName("compare")).bind("find_fun")), + // ... on a class with a starts_with function... + on(hasType( + hasCanonicalType(hasDeclaration(ClassWithStartsWithFunction)))), + // ... where the third argument is some string and the second a length. + HasStringAndLengthArgs(2, 1), + // Bind search expression. + hasArgument(2, expr().bind("search_expr"))); Finder->addMatcher( - // Match [=!]= with a zero on one side and a string.(r?)find on the other. - binaryOperator(hasAnyOperatorName("==", "!="), - hasOperands(FindOrRFindExpr, ZeroLiteral)) + // Match [=!]= with a zero on one side and (r?)find|compare on the other. + binaryOperator( + hasAnyOperatorName("==", "!="), + hasOperands(cxxMemberCallExpr(anyOf(FindExpr, RFindExpr, CompareExpr)) + .bind("find_expr"), + ZeroLiteral)) .bind("expr"), this); } @@ -69,9 +124,28 @@ void UseStartsEndsWithCheck::check(const MatchFinder::MatchResult &Result) { const auto *ComparisonExpr = Result.Nodes.getNodeAs("expr"); const auto *FindExpr = Result.Nodes.getNodeAs("find_expr"); const auto *FindFun = Result.Nodes.getNodeAs("find_fun"); + const auto *SearchExpr = Result.Nodes.getNodeAs("search_expr"); const auto *StartsWithFunction = Result.Nodes.getNodeAs("starts_with_fun"); + const auto *StringLiteralArg = + Result.Nodes.getNodeAs("string_literal_arg"); + const auto *IntegerLiteralSizeArg = + Result.Nodes.getNodeAs("integer_literal_size_arg"); + const auto *StrlenArg = Result.Nodes.getNodeAs("strlen_arg"); + + // Filter out compare cases where the length does not match string literal. + if (StringLiteralArg && IntegerLiteralSizeArg && + StringLiteralArg->getLength() != + IntegerLiteralSizeArg->getValue().getZExtValue()) { + return; + } + + if (StringLiteralArg && StrlenArg && + StringLiteralArg->getLength() != StrlenArg->getLength()) { + return; + } + if (ComparisonExpr->getBeginLoc().isMacroID()) { return; } @@ -79,13 +153,13 @@ void UseStartsEndsWithCheck::check(const MatchFinder::MatchResult &Result) { const bool Neg = ComparisonExpr->getOpcode() == BO_NE; auto Diagnostic = - diag(FindExpr->getBeginLoc(), "use %0 instead of %1() %select{==|!=}2 0") + diag(FindExpr->getExprLoc(), "use %0 instead of %1() %select{==|!=}2 0") << StartsWithFunction->getName() << FindFun->getName() << Neg; - // Remove possible zero second argument and ' [!=]= 0' suffix. + // Remove possible arguments after search expression and ' [!=]= 0' suffix. Diagnostic << FixItHint::CreateReplacement( CharSourceRange::getTokenRange( - Lexer::getLocForEndOfToken(FindExpr->getArg(0)->getEndLoc(), 0, + Lexer::getLocForEndOfToken(SearchExpr->getEndLoc(), 0, *Result.SourceManager, getLangOpts()), ComparisonExpr->getEndLoc()), ")"); @@ -94,11 +168,12 @@ void UseStartsEndsWithCheck::check(const MatchFinder::MatchResult &Result) { Diagnostic << FixItHint::CreateRemoval(CharSourceRange::getCharRange( ComparisonExpr->getBeginLoc(), FindExpr->getBeginLoc())); - // Replace '(r?)find' with 'starts_with'. + // Replace method name by 'starts_with'. + // Remove possible arguments before search expression. Diagnostic << FixItHint::CreateReplacement( - CharSourceRange::getTokenRange(FindExpr->getExprLoc(), - FindExpr->getExprLoc()), - StartsWithFunction->getName()); + CharSourceRange::getCharRange(FindExpr->getExprLoc(), + SearchExpr->getBeginLoc()), + (StartsWithFunction->getName() + "(").str()); // Add possible negation '!'. if (Neg) { diff --git a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h index 34e971776825..840191f32149 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseStartsEndsWithCheck.h @@ -13,9 +13,10 @@ namespace clang::tidy::modernize { -/// Checks whether a ``find`` or ``rfind`` result is compared with 0 and -/// suggests replacing with ``starts_with`` when the method exists in the class. -/// Notably, this will work with ``std::string`` and ``std::string_view``. +/// Checks for common roundabout ways to express ``starts_with`` and +/// ``ends_with`` and suggests replacing with ``starts_with`` when the method is +/// available. Notably, this will work with ``std::string`` and +/// ``std::string_view``. /// /// For the user-facing documentation see: /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-starts-ends-with.html diff --git a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp index 48bca41f4a3b..f077040a3529 100644 --- a/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/AvoidReturnWithVoidValueCheck.cpp @@ -64,8 +64,11 @@ void AvoidReturnWithVoidValueCheck::check( << BraceInsertionHints.closingBraceFixIt(); } Diag << FixItHint::CreateRemoval(VoidReturn->getReturnLoc()); - if (!Result.Nodes.getNodeAs("function_parent") || - SurroundingBlock->body_back() != VoidReturn) + const auto *FunctionParent = + Result.Nodes.getNodeAs("function_parent"); + if (!FunctionParent || + (SurroundingBlock && SurroundingBlock->body_back() != VoidReturn)) + // If this is not the last statement in a function body, we add a `return`. Diag << FixItHint::CreateInsertion(SemicolonPos.getLocWithOffset(1), " return;", true); } diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt index dd772d692025..41065fc8e878 100644 --- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt @@ -28,6 +28,7 @@ add_clang_library(clangTidyReadabilityModule IsolateDeclarationCheck.cpp MagicNumbersCheck.cpp MakeMemberFunctionConstCheck.cpp + MathMissingParenthesesCheck.cpp MisleadingIndentationCheck.cpp MisplacedArrayIndexCheck.cpp NamedParameterCheck.cpp diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp new file mode 100644 index 000000000000..d1e20b9074ce --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.cpp @@ -0,0 +1,97 @@ +//===--- MathMissingParenthesesCheck.cpp - clang-tidy ---------------------===// +// +// Part of the LLVM Project, under the Apache 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 "MathMissingParenthesesCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::readability { + +void MathMissingParenthesesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(binaryOperator(unless(hasParent(binaryOperator())), + unless(isAssignmentOperator()), + unless(isComparisonOperator()), + unless(hasAnyOperatorName("&&", "||")), + hasDescendant(binaryOperator())) + .bind("binOp"), + this); +} + +static int getPrecedence(const BinaryOperator *BinOp) { + if (!BinOp) + return 0; + switch (BinOp->getOpcode()) { + case BO_Mul: + case BO_Div: + case BO_Rem: + return 5; + case BO_Add: + case BO_Sub: + return 4; + case BO_And: + return 3; + case BO_Xor: + return 2; + case BO_Or: + return 1; + default: + return 0; + } +} +static void addParantheses(const BinaryOperator *BinOp, + const BinaryOperator *ParentBinOp, + ClangTidyCheck *Check, + const clang::SourceManager &SM, + const clang::LangOptions &LangOpts) { + if (!BinOp) + return; + + int Precedence1 = getPrecedence(BinOp); + int Precedence2 = getPrecedence(ParentBinOp); + + if (ParentBinOp != nullptr && Precedence1 != Precedence2) { + const clang::SourceLocation StartLoc = BinOp->getBeginLoc(); + const clang::SourceLocation EndLoc = + clang::Lexer::getLocForEndOfToken(BinOp->getEndLoc(), 0, SM, LangOpts); + if (EndLoc.isInvalid()) + return; + + Check->diag(StartLoc, + "'%0' has higher precedence than '%1'; add parentheses to " + "explicitly specify the order of operations") + << (Precedence1 > Precedence2 ? BinOp->getOpcodeStr() + : ParentBinOp->getOpcodeStr()) + << (Precedence1 > Precedence2 ? ParentBinOp->getOpcodeStr() + : BinOp->getOpcodeStr()) + << FixItHint::CreateInsertion(StartLoc, "(") + << FixItHint::CreateInsertion(EndLoc, ")") + << SourceRange(StartLoc, EndLoc); + } + + addParantheses(dyn_cast(BinOp->getLHS()->IgnoreImpCasts()), + BinOp, Check, SM, LangOpts); + addParantheses(dyn_cast(BinOp->getRHS()->IgnoreImpCasts()), + BinOp, Check, SM, LangOpts); +} + +void MathMissingParenthesesCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binOp"); + std::vector< + std::pair>> + Insertions; + const SourceManager &SM = *Result.SourceManager; + const clang::LangOptions &LO = Result.Context->getLangOpts(); + addParantheses(BinOp, nullptr, this, SM, LO); +} + +} // namespace clang::tidy::readability diff --git a/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h new file mode 100644 index 000000000000..9a9d2b3cfaab --- /dev/null +++ b/clang-tools-extra/clang-tidy/readability/MathMissingParenthesesCheck.h @@ -0,0 +1,34 @@ +//===--- MathMissingParenthesesCheck.h - clang-tidy -------------*- 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_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H + +#include "../ClangTidyCheck.h" + +namespace clang::tidy::readability { + +/// Check for mising parantheses in mathematical expressions that involve +/// operators of different priorities. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/readability/math-missing-parentheses.html +class MathMissingParenthesesCheck : public ClangTidyCheck { +public: + MathMissingParenthesesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + std::optional getCheckTraversalKind() const override { + return TK_IgnoreUnlessSpelledInSource; + } +}; + +} // namespace clang::tidy::readability + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_MATHMISSINGPARENTHESESCHECK_H diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp index 376b84683df7..d61c0ba39658 100644 --- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -32,6 +32,7 @@ #include "IsolateDeclarationCheck.h" #include "MagicNumbersCheck.h" #include "MakeMemberFunctionConstCheck.h" +#include "MathMissingParenthesesCheck.h" #include "MisleadingIndentationCheck.h" #include "MisplacedArrayIndexCheck.h" #include "NamedParameterCheck.h" @@ -105,6 +106,8 @@ public: "readability-identifier-naming"); CheckFactories.registerCheck( "readability-implicit-bool-conversion"); + CheckFactories.registerCheck( + "readability-math-missing-parentheses"); CheckFactories.registerCheck( "readability-redundant-inline-specifier"); CheckFactories.registerCheck( diff --git a/clang-tools-extra/clangd/CodeCompletionStrings.cpp b/clang-tools-extra/clangd/CodeCompletionStrings.cpp index 2075e5965f18..9b4442b0bb76 100644 --- a/clang-tools-extra/clangd/CodeCompletionStrings.cpp +++ b/clang-tools-extra/clangd/CodeCompletionStrings.cpp @@ -253,7 +253,7 @@ void getSignature(const CodeCompletionString &CCS, std::string *Signature, if (!IncludeFunctionArguments && ResultKind == CodeCompletionResult::RK_Declaration) TruncateSnippetAt.emplace(Snippet->size()); - LLVM_FALLTHROUGH; + [[fallthrough]]; case CodeCompletionString::CK_RightParen: case CodeCompletionString::CK_LeftBracket: case CodeCompletionString::CK_RightBracket: diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index f3f9a81f9a8e..3038d2b125f2 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -100,11 +100,15 @@ Improvements to clang-tidy - Improved :program:`run-clang-tidy.py` script. Added argument `-source-filter` to filter source files from the compilation database, via a RegEx. In a similar fashion to what `-header-filter` does for header files. + - Improved :program:`check_clang_tidy.py` script. Added argument `-export-fixes` to aid in clang-tidy and test development. -- Fixed ``--verify-config`` option not properly parsing checks when using the - literal operator in the ``.clang-tidy`` config. +- Fixed bug where big values for unsigned check options overflowed into negative values + when being printed with `--dump-config`. + +- Fixed `--verify-config` option not properly parsing checks when using the + literal operator in the `.clang-tidy` config. New checks ^^^^^^^^^^ @@ -115,6 +119,13 @@ New checks Detects error-prone Curiously Recurring Template Pattern usage, when the CRTP can be constructed outside itself and the derived class. +- New :doc:`bugprone-return-const-ref-from-parameter + ` check. + + Detects return statements that return a constant reference parameter as constant + reference. This may cause use-after-free errors if the caller uses xvalues as + arguments. + - New :doc:`bugprone-suspicious-stringview-data-usage ` check. @@ -122,6 +133,12 @@ New checks to reading out-of-bounds data due to inadequate or incorrect string null termination. +- New :doc:`modernize-min-max-use-initializer-list + ` check. + + Replaces nested ``std::min`` and ``std::max`` calls with an initializer list + where applicable. + - New :doc:`modernize-use-designated-initializers ` check. @@ -134,6 +151,12 @@ New checks Enforces consistent style for enumerators' initialization, covering three styles: none, first only, or all initialized explicitly. +- New :doc:`readability-math-missing-parentheses + ` check. + + Check for missing parentheses in mathematical expressions that involve + operators of different priorities. + - New :doc:`readability-use-std-min-max ` check. @@ -215,7 +238,7 @@ Changes in existing checks - Improved :doc:`google-explicit-constructor ` check to better handle - ``C++-20`` `explicit(bool)`. + C++20 `explicit(bool)`. - Improved :doc:`google-global-names-in-headers ` check by replacing the local @@ -228,6 +251,10 @@ Changes in existing checks check by ignoring other functions with same prefixes as the target specific functions. +- Improved :doc:`linuxkernel-must-check-errs + ` check documentation to + consistently use the check's proper name. + - Improved :doc:`llvm-header-guard ` check by replacing the local option `HeaderFileExtensions` by the global option of the same name. @@ -260,10 +287,18 @@ Changes in existing checks don't remove parentheses used in ``sizeof`` calls when they have array index accesses as arguments. +- Improved :doc:`modernize-use-nullptr + ` check to include support for C23, + which also has introduced the ``nullptr`` keyword. + - Improved :doc:`modernize-use-override ` check to also remove any trailing whitespace when deleting the ``virtual`` keyword. +- Improved :doc:`modernize-use-starts-ends-with + ` check to also handle + calls to ``compare`` method. + - Improved :doc:`modernize-use-using ` check by adding support for detection of typedefs declared on function level. @@ -311,13 +346,9 @@ Miscellaneous ^^^^^^^^^^^^^ - Fixed incorrect formatting in :program:`clang-apply-replacements` when no - ``--format`` option is specified. Now :program:`clang-apply-replacements` + `--format` option is specified. Now :program:`clang-apply-replacements` applies formatting only with the option. -- Fixed the :doc:`linuxkernel-must-check-errs - ` documentation to consistently - use the check's proper name. - Improvements to include-fixer ----------------------------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst new file mode 100644 index 000000000000..f007dfe54999 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/return-const-ref-from-parameter.rst @@ -0,0 +1,31 @@ +.. title:: clang-tidy - bugprone-return-const-ref-from-parameter + +bugprone-return-const-ref-from-parameter +======================================== + +Detects return statements that return a constant reference parameter as constant +reference. This may cause use-after-free errors if the caller uses xvalues as +arguments. + +In C++, constant reference parameters can accept xvalues which will be destructed +after the call. When the function returns such a parameter also as constant reference, +then the returned reference can be used after the object it refers to has been +destroyed. + +Example +------- + +.. code-block:: c++ + + struct S { + int v; + S(int); + ~S(); + }; + + const S &fn(const S &a) { + return a; + } + + const S& s = fn(S{1}); + s.v; // use after free diff --git a/clang-tools-extra/docs/clang-tidy/checks/cert/env33-c.rst b/clang-tools-extra/docs/clang-tidy/checks/cert/env33-c.rst index c5321b07f7f8..9271c9ecccc0 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/cert/env33-c.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cert/env33-c.rst @@ -10,4 +10,4 @@ but does not actually attempt to execute a command. This check corresponds to the CERT C Coding Standard rule `ENV33-C. Do not call system() -`_. +`_. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index 3a06d7c30c9b..49747ff896ba 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -120,6 +120,7 @@ Clang-Tidy Checks :doc:`bugprone-posix-return `, "Yes" :doc:`bugprone-redundant-branch-condition `, "Yes" :doc:`bugprone-reserved-identifier `, "Yes" + :doc:`bugprone-return-const-ref-from-parameter ` :doc:`bugprone-shared-ptr-array-mismatch `, "Yes" :doc:`bugprone-signal-handler `, :doc:`bugprone-signed-char-misuse `, @@ -275,6 +276,7 @@ Clang-Tidy Checks :doc:`modernize-macro-to-enum `, "Yes" :doc:`modernize-make-shared `, "Yes" :doc:`modernize-make-unique `, "Yes" + :doc:`modernize-min-max-use-initializer-list `, "Yes" :doc:`modernize-pass-by-value `, "Yes" :doc:`modernize-raw-string-literal `, "Yes" :doc:`modernize-redundant-void-arg `, "Yes" @@ -362,6 +364,7 @@ Clang-Tidy Checks :doc:`readability-isolate-declaration `, "Yes" :doc:`readability-magic-numbers `, :doc:`readability-make-member-function-const `, "Yes" + :doc:`readability-math-missing-parentheses `, "Yes" :doc:`readability-misleading-indentation `, :doc:`readability-misplaced-array-index `, "Yes" :doc:`readability-named-parameter `, "Yes" diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/min-max-use-initializer-list.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/min-max-use-initializer-list.rst new file mode 100644 index 000000000000..d6721a25629b --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/min-max-use-initializer-list.rst @@ -0,0 +1,50 @@ +.. title:: clang-tidy - modernize-min-max-use-initializer-list + +modernize-min-max-use-initializer-list +====================================== + +Replaces nested ``std::min`` and ``std::max`` calls with an initializer list +where applicable. + +For instance, consider the following code: + +.. code-block:: cpp + + int a = std::max(std::max(i, j), k); + +The check will transform the above code to: + +.. code-block:: cpp + + int a = std::max({i, j, k}); + +Performance Considerations +========================== + +While this check simplifies the code and makes it more readable, it may cause +performance degradation for non-trivial types due to the need to copy objects +into the initializer list. + +To avoid this, it is recommended to use `std::ref` or `std::cref` for +non-trivial types: + +.. code-block:: cpp + + std::string b = std::max({std::ref(i), std::ref(j), std::ref(k)}); + +Options +======= + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. Default + is `llvm`. + +.. option:: IgnoreNonTrivialTypes + + A boolean specifying whether to ignore non-trivial types. Default is `true`. + +.. option:: IgnoreTrivialTypesOfSizeAbove + + An integer specifying the size (in bytes) above which trivial types are + ignored. Default is `32`. \ No newline at end of file diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst index 5e1ba858adf3..25e17fee0a3d 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-nullptr.rst @@ -4,7 +4,7 @@ modernize-use-nullptr ===================== The check converts the usage of null pointer constants (e.g. ``NULL``, ``0``) -to use the new C++11 ``nullptr`` keyword. +to use the new C++11 and C23 ``nullptr`` keyword. Example ------- diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst index 7f8a262d2ab3..34237ede30a3 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-starts-ends-with.rst @@ -3,15 +3,16 @@ modernize-use-starts-ends-with ============================== -Checks whether a ``find`` or ``rfind`` result is compared with 0 and suggests -replacing with ``starts_with`` when the method exists in the class. Notably, -this will work with ``std::string`` and ``std::string_view``. +Checks for common roundabout ways to express ``starts_with`` and ``ends_with`` +and suggests replacing with ``starts_with`` when the method is available. +Notably, this will work with ``std::string`` and ``std::string_view``. .. code-block:: c++ std::string s = "..."; if (s.find("prefix") == 0) { /* do something */ } if (s.rfind("prefix", 0) == 0) { /* do something */ } + if (s.compare(0, strlen("prefix"), "prefix") == 0) { /* do something */ } becomes @@ -20,3 +21,4 @@ becomes std::string s = "..."; if (s.starts_with("prefix")) { /* do something */ } if (s.starts_with("prefix")) { /* do something */ } + if (s.starts_with("prefix")) { /* do something */ } diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst new file mode 100644 index 000000000000..21d66daab334 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/readability/math-missing-parentheses.rst @@ -0,0 +1,27 @@ +.. title:: clang-tidy - readability-math-missing-parentheses + +readability-math-missing-parentheses +==================================== + +Check for missing parentheses in mathematical expressions that involve operators +of different priorities. + +Parentheses in mathematical expressions clarify the order +of operations, especially with different-priority operators. Lengthy or multiline +expressions can obscure this order, leading to coding errors. IDEs can aid clarity +by highlighting parentheses. Explicitly using parentheses also clarifies what the +developer had in mind when writing the expression. Ensuring their presence reduces +ambiguity and errors, promoting clearer and more maintainable code. + +Before: + +.. code-block:: c++ + + int x = 1 + 2 * 3 - 4 / 5; + + +After: + +.. code-block:: c++ + + int x = 1 + (2 * 3) - (4 / 5); \ No newline at end of file diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string index 28e2b4a231e5..d031f27beb9d 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string @@ -44,6 +44,8 @@ struct basic_string { int compare(const C* s) const; int compare(size_type pos, size_type len, const _Type&) const; int compare(size_type pos, size_type len, const C* s) const; + template + int compare(size_type pos1, size_type count1, const StringViewLike& t) const; size_type find(const _Type& str, size_type pos = 0) const; size_type find(const C* s, size_type pos = 0) const; @@ -129,6 +131,8 @@ bool operator!=(const char*, const std::string&); bool operator==(const std::wstring&, const std::wstring&); bool operator==(const std::wstring&, const wchar_t*); bool operator==(const wchar_t*, const std::wstring&); + +size_t strlen(const char* str); } #endif // _STRING_ diff --git a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string.h b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string.h index 4ab7e930e4b5..af205868059a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string.h +++ b/clang-tools-extra/test/clang-tidy/checkers/Inputs/Headers/string.h @@ -12,5 +12,6 @@ #include "stddef.h" void *memcpy(void *dest, const void *src, size_t n); +size_t strlen(const char* str); #endif // _STRING_H_ diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp index ecd17bba293c..dbd354b132e2 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil/redundant-strcat-calls.cpp @@ -1,8 +1,6 @@ // RUN: %check_clang_tidy %s abseil-redundant-strcat-calls %t -- -- -isystem %clang_tidy_headers #include -int strlen(const char *); - namespace absl { class string_view { diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp new file mode 100644 index 000000000000..a83a019ec743 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp @@ -0,0 +1,31 @@ +// RUN: %check_clang_tidy %s bugprone-return-const-ref-from-parameter %t + +using T = int; +using TConst = int const; +using TConstRef = int const&; + +namespace invalid { + +int const &f1(int const &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: returning a constant reference parameter + +int const &f2(T const &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: returning a constant reference parameter + +int const &f3(TConstRef a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: returning a constant reference parameter + +int const &f4(TConst &a) { return a; } +// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: returning a constant reference parameter + +} // namespace invalid + +namespace valid { + +int const &f1(int &a) { return a; } + +int const &f2(int &&a) { return a; } + +int f1(int const &a) { return a; } + +} // namespace valid diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp new file mode 100644 index 000000000000..51ab9bda975f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/min-max-use-initializer-list.cpp @@ -0,0 +1,305 @@ +// RUN: %check_clang_tidy %s modernize-min-max-use-initializer-list %t + +// CHECK-FIXES: #include +namespace utils { +template +T max(T a, T b) { + return (a < b) ? b : a; +} +} // namespace utils + +namespace std { +template< class T > +struct initializer_list { + initializer_list()=default; + initializer_list(T*,int){} + const T* begin() const {return nullptr;} + const T* end() const {return nullptr;} +}; + +template +ForwardIt min_element(ForwardIt first, ForwardIt last) +{ + if (first == last) + return last; + + ForwardIt smallest = first; + + while (++first != last) + if (*first < *smallest) + smallest = first; + + return smallest; +} + +template +ForwardIt min_element(ForwardIt first, ForwardIt last, Compare comp) +{ + if (first == last) + return last; + + ForwardIt smallest = first; + + while (++first != last) + if (comp(*first, *smallest)) + smallest = first; + + return smallest; +} + +template +ForwardIt max_element(ForwardIt first, ForwardIt last) +{ + if (first == last) + return last; + + ForwardIt largest = first; + + while (++first != last) + if (*largest < *first) + largest = first; + + return largest; +} + +template +ForwardIt max_element(ForwardIt first, ForwardIt last, Compare comp) +{ + if (first == last) + return last; + + ForwardIt largest = first; + + while(++first != last) + if (comp(*largest, *first)) + largest = first; + + return largest; +} + +template< class T > +const T& max( const T& a, const T& b ) { + return (a < b) ? b : a; +}; + +template< class T > +T max(std::initializer_list ilist) +{ + return *std::max_element(ilist.begin(), ilist.end()); +} + +template< class T, class Compare > +const T& max( const T& a, const T& b, Compare comp ) { + return (comp(a, b)) ? b : a; +}; + +template< class T, class Compare > +T max(std::initializer_list ilist, Compare comp) { + return *std::max_element(ilist.begin(), ilist.end(), comp); +}; + +template< class T > +const T& min( const T& a, const T& b ) { + return (b < a) ? b : a; +}; + +template< class T > +T min(std::initializer_list ilist) +{ + return *std::min_element(ilist.begin(), ilist.end()); +} + + +template< class T, class Compare > +const T& min( const T& a, const T& b, Compare comp ) { + return (comp(b, a)) ? b : a; +}; + +template< class T, class Compare > +T min(std::initializer_list ilist, Compare comp) { + return *std::min_element(ilist.begin(), ilist.end(), comp); +}; + +} // namespace std + +using namespace std; + +namespace { +bool fless_than(int a, int b) { +return a < b; +} + +bool fgreater_than(int a, int b) { +return a > b; +} +auto less_than = [](int a, int b) { return a < b; }; +auto greater_than = [](int a, int b) { return a > b; }; + +int max1 = std::max(1, std::max(2, 3)); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max1 = std::max({1, 2, 3}); + +int min1 = std::min(1, std::min(2, 3)); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min1 = std::min({1, 2, 3}); + +int max2 = std::max(1, std::max(2, std::max(3, 4))); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max2 = std::max({1, 2, 3, 4}); + +int max2b = std::max(std::max(std::max(1, 2), std::max(3, 4)), std::max(std::max(5, 6), std::max(7, 8))); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max2b = std::max({1, 2, 3, 4, 5, 6, 7, 8}); + +int max2c = std::max(std::max(1, std::max(2, 3)), 4); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max2c = std::max({1, 2, 3, 4}); + +int max2d = std::max(std::max({1, 2, 3}), 4); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max2d = std::max({1, 2, 3, 4}); + + +int max2e = std::max(1, max(2, max(3, 4))); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max2e = std::max({1, 2, 3, 4}); + +int min2 = std::min(1, std::min(2, std::min(3, 4))); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min2 = std::min({1, 2, 3, 4}); + +int max3 = std::max(std::max(4, 5), std::min(2, std::min(3, 1))); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max3 = std::max({4, 5, std::min({2, 3, 1})}); + +int min3 = std::min(std::min(4, 5), std::max(2, std::max(3, 1))); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min3 = std::min({4, 5, std::max({2, 3, 1})}); + +int max4 = std::max(1, std::max(2, 3, greater_than), less_than); +// CHECK-FIXES: int max4 = std::max(1, std::max(2, 3, greater_than), less_than); + +int min4 = std::min(1, std::min(2, 3, greater_than), less_than); +// CHECK-FIXES: int min4 = std::min(1, std::min(2, 3, greater_than), less_than); + +int max5 = std::max(1, std::max(2, 3), less_than); +// CHECK-FIXES: int max5 = std::max(1, std::max(2, 3), less_than); + +int min5 = std::min(1, std::min(2, 3), less_than); +// CHECK-FIXES: int min5 = std::min(1, std::min(2, 3), less_than); + +int max6 = std::max(1, std::max(2, 3, greater_than), greater_than); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max6 = std::max({1, 2, 3 }, greater_than); + +int min6 = std::min(1, std::min(2, 3, greater_than), greater_than); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min6 = std::min({1, 2, 3 }, greater_than); + +int max7 = std::max(1, std::max(2, 3, fless_than), fgreater_than); +// CHECK-FIXES: int max7 = std::max(1, std::max(2, 3, fless_than), fgreater_than); + +int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than); +// CHECK-FIXES: int min7 = std::min(1, std::min(2, 3, fless_than), fgreater_than); + +int max8 = std::max(1, std::max(2, 3, fless_than), less_than); +// CHECK-FIXES: int max8 = std::max(1, std::max(2, 3, fless_than), less_than) + +int min8 = std::min(1, std::min(2, 3, fless_than), less_than); +// CHECK-FIXES: int min8 = std::min(1, std::min(2, 3, fless_than), less_than); + +int max9 = std::max(1, std::max(2, 3, fless_than), fless_than); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max9 = std::max({1, 2, 3 }, fless_than); + +int min9 = std::min(1, std::min(2, 3, fless_than), fless_than); +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min9 = std::min({1, 2, 3 }, fless_than); + +int min10 = std::min(std::min(4, 5), std::max(2, utils::max(3, 1))); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::min' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int min10 = std::min({4, 5, std::max(2, utils::max(3, 1))}); + +int max10 = std::max({std::max(1, 2), std::max({5, 6, 1}), 2, std::min({1, 2, 4})}); +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int max10 = std::max({1, 2, 5, 6, 1, 2, std::min({1, 2, 4})}); + +int typecastTest = std::max(std::max(0U, 0.0f), 0); +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int typecastTest = std::max({static_cast(0U), static_cast(0.0f), 0}); + +int typecastTest1 = std::max(std::max(0U, 0.0f), 0L); +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int typecastTest1 = std::max({static_cast(0U), static_cast(0.0f), 0L}); + +int typecastTest2 = std::max(std::max(10U, 20.0f), 30); +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int typecastTest2 = std::max({static_cast(10U), static_cast(20.0f), 30}); + +int typecastTest3 = std::max(std::max(0U, std::max(0.0f, 1.0f)), 0); +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int typecastTest3 = std::max({static_cast(0U), static_cast(0.0f), static_cast(1.0f), 0}); + +#define max3f(a, b, c) std::max(a, std::max(b, c)) +// CHECK-FIXES: #define max3f(a, b, c) std::max(a, std::max(b, c)) + +#define value 4545 +int macroVarMax = std::max(value, std::max(1, 2)); +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int macroVarMax = std::max({value, 1, 2}); + +#define value2 45U +int macroVarMax2 = std::max(1, std::max(value2, 2.0f)); +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: do not use nested 'std::max' calls, use an initializer list instead [modernize-min-max-use-initializer-list] +// CHECK-FIXES: int macroVarMax2 = std::max({1, static_cast(value2), static_cast(2.0f)}); + +// True-negative tests +int maxTN1 = std::max(1, 2); +// CHECK-FIXES: int maxTN1 = std::max(1, 2); + +int maxTN2 = std::max({1, 2, 3}); +// CHECK-FIXES: int maxTN2 = std::max({1, 2, 3}); + +int maxTN3 = std::max({1, 2, 3}, less_than); +// CHECK-FIXES: int maxTN3 = std::max({1, 2, 3}, less_than); + +// non-trivial types +struct A { + int a; + A(int a) : a(a) {} + bool operator<(const A &rhs) const { return a < rhs.a; } +}; + +A maxNT1 = std::max(A(1), A(2)); +// CHECK-FIXES: A maxNT1 = std::max(A(1), A(2)); + +A maxNT2 = std::max(A(1), std::max(A(2), A(3))); +// CHECK-FIXES: A maxNT2 = std::max(A(1), std::max(A(2), A(3))); + +A maxNT3 = std::max(A(1), std::max(A(2), A(3)), [](const A &lhs, const A &rhs) { return lhs.a < rhs.a; }); +// CHECK-FIXES: A maxNT3 = std::max(A(1), std::max(A(2), A(3)), [](const A &lhs, const A &rhs) { return lhs.a < rhs.a; }); + +// Trivial type with size greater than 32 +struct B { + // 9*4 = 36 bytes > 32 bytes + int a[9]; + + bool operator<(const B& rhs) const { + return a[0] < rhs.a[0]; + } +}; + +B maxTT1 = std::max(B(), B()); +// CHECK-FIXES: B maxTT1 = std::max(B(), B()); + +B maxTT2 = std::max(B(), std::max(B(), B())); +// CHECK-FIXES: B maxTT2 = std::max(B(), std::max(B(), B())); + +B maxTT3 = std::max(B(), std::max(B(), B()), [](const B &lhs, const B &rhs) { return lhs.a[0] < rhs.a[0]; }); +// CHECK-FIXES: B maxTT3 = std::max(B(), std::max(B(), B()), [](const B &lhs, const B &rhs) { return lhs.a[0] < rhs.a[0]; }); + + +} // namespace + diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c new file mode 100644 index 000000000000..6fb879b91e41 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr-c23.c @@ -0,0 +1,139 @@ +// RUN: %check_clang_tidy %s modernize-use-nullptr %t -- -- -std=c23 + +#define NULL 0 + +void test_assignment() { + int *p1 = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr [modernize-use-nullptr] + // CHECK-FIXES: int *p1 = nullptr; + p1 = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr + // CHECK-FIXES: p1 = nullptr; + + int *p2 = NULL; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr + // CHECK-FIXES: int *p2 = nullptr; + + p2 = p1; + // CHECK-FIXES: p2 = p1; + + const int null = 0; + int *p3 = &null; + + p3 = NULL; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use nullptr + // CHECK-FIXES: p3 = nullptr; + + int *p4 = p3; + + int i1 = 0; + + int i2 = NULL; + + int i3 = null; + + int *p5, *p6, *p7; + p5 = p6 = p7 = NULL; + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: use nullptr + // CHECK-FIXES: p5 = p6 = p7 = nullptr; +} + +void test_function(int *p) {} + +void test_function_no_ptr_param(int i) {} + +void test_function_call() { + test_function(0); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr + // CHECK-FIXES: test_function(nullptr); + + test_function(NULL); + // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use nullptr + // CHECK-FIXES: test_function(nullptr); + + test_function_no_ptr_param(0); +} + +char *test_function_return1() { + return 0; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr + // CHECK-FIXES: return nullptr; +} + +void *test_function_return2() { + return NULL; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr + // CHECK-FIXES: return nullptr; +} + +int test_function_return4() { + return 0; +} + +int test_function_return5() { + return NULL; +} + +int *test_function_return_cast1() { + return(int)0; + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use nullptr + // CHECK-FIXES: return nullptr; +} + +int *test_function_return_cast2() { +#define RET return + RET(int)0; + // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use nullptr + // CHECK-FIXES: RET nullptr; +#undef RET +} + +// Test parentheses expressions resulting in a nullptr. +int *test_parentheses_expression1() { + return(0); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr + // CHECK-FIXES: return(nullptr); +} + +int *test_parentheses_expression2() { + return((int)(0.0f)); + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use nullptr + // CHECK-FIXES: return(nullptr); +} + +int *test_nested_parentheses_expression() { + return((((0)))); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use nullptr + // CHECK-FIXES: return((((nullptr)))); +} + +void test_const_pointers() { + const int *const_p1 = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr + // CHECK-FIXES: const int *const_p1 = nullptr; + const int *const_p2 = NULL; + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr + // CHECK-FIXES: const int *const_p2 = nullptr; + const int *const_p3 = (int)0; + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr + // CHECK-FIXES: const int *const_p3 = nullptr; + const int *const_p4 = (int)0.0f; + // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use nullptr + // CHECK-FIXES: const int *const_p4 = nullptr; +} + +void test_nested_implicit_cast_expr() { + int func0(void*, void*); + int func1(int, void*, void*); + + (double)func1(0, 0, 0); + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use nullptr + // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: use nullptr + // CHECK-FIXES: (double)func1(0, nullptr, nullptr); + (double)func1(func0(0, 0), 0, 0); + // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: use nullptr + // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use nullptr + // CHECK-MESSAGES: :[[@LINE-3]]:30: warning: use nullptr + // CHECK-MESSAGES: :[[@LINE-4]]:33: warning: use nullptr + // CHECK-FIXES: (double)func1(func0(nullptr, nullptr), nullptr, nullptr); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.c b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.c index c2ccbbd81171..1218b837199c 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.c +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-nullptr.c @@ -1,4 +1,4 @@ -// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- | count 0 +// RUN: clang-tidy %s -checks=-*,modernize-use-nullptr -- -std=c17 | count 0 // Note: this test expects no diagnostics, but FileCheck cannot handle that, // hence the use of | count 0. diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp index 65ed9ed895bc..c5b2c86befd1 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-starts-ends-with.cpp @@ -1,6 +1,7 @@ // RUN: %check_clang_tidy -std=c++20 %s modernize-use-starts-ends-with %t -- \ // RUN: -- -isystem %clang_tidy_headers +#include #include std::string foo(std::string); @@ -158,10 +159,64 @@ void test(std::string s, std::string_view sv, sub_string ss, sub_sub_string sss, // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use startsWith // CHECK-FIXES: puvi.startsWith("a"); + s.compare(0, 1, "a") == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare() == 0 + // CHECK-FIXES: s.starts_with("a"); + + s.compare(0, 1, "a") != 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with instead of compare() != 0 + // CHECK-FIXES: !s.starts_with("a"); + + s.compare(0, strlen("a"), "a") == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with("a"); + + s.compare(0, std::strlen("a"), "a") == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with("a"); + + s.compare(0, std::strlen(("a")), "a") == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with("a"); + + s.compare(0, std::strlen(("a")), (("a"))) == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with("a"); + + s.compare(0, s.size(), s) == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with(s); + + s.compare(0, s.length(), s) == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with(s); + + 0 != s.compare(0, sv.length(), sv); + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with(sv); + + #define LENGTH(x) (x).length() + s.compare(0, LENGTH(s), s) == 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with(s); + + s.compare(ZERO, LENGTH(s), s) == ZERO; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: s.starts_with(s); + + s.compare(ZERO, LENGTH(sv), sv) != 0; + // CHECK-MESSAGES: :[[@LINE-1]]:{{[0-9]+}}: warning: use starts_with + // CHECK-FIXES: !s.starts_with(sv); + // Expressions that don't trigger the check are here. #define EQ(x, y) ((x) == (y)) EQ(s.find("a"), 0); #define DOTFIND(x, y) (x).find(y) DOTFIND(s, "a") == 0; + + #define STARTS_WITH_COMPARE(x, y) (x).compare(0, (x).size(), (y)) + STARTS_WITH_COMPARE(s, s) == 0; + + s.compare(0, 1, "ab") == 0; } diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp new file mode 100644 index 000000000000..edbe2e1c37c7 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability/math-missing-parentheses.cpp @@ -0,0 +1,120 @@ +// RUN: %check_clang_tidy %s readability-math-missing-parentheses %t + +#define MACRO_AND & +#define MACRO_ADD + +#define MACRO_OR | +#define MACRO_MULTIPLY * +#define MACRO_XOR ^ +#define MACRO_SUBTRACT - +#define MACRO_DIVIDE / + +int foo(){ + return 5; +} + +int bar(){ + return 4; +} + +class fun{ +public: + int A; + double B; + fun(){ + A = 5; + B = 5.4; + } +}; + +void f(){ + //CHECK-MESSAGES: :[[@LINE+2]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int a = 1 + (2 * 3); + int a = 1 + 2 * 3; + + int a_negative = 1 + (2 * 3); // No warning + + int b = 1 + 2 + 3; // No warning + + int c = 1 * 2 * 3; // No warning + + //CHECK-MESSAGES: :[[@LINE+3]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+2]]:25: warning: '/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int d = 1 + (2 * 3) - (4 / 5); + int d = 1 + 2 * 3 - 4 / 5; + + int d_negative = 1 + (2 * 3) - (4 / 5); // No warning + + //CHECK-MESSAGES: :[[@LINE+4]]:13: warning: '&' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+3]]:17: warning: '+' has higher precedence than '&'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+2]]:25: warning: '*' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int e = (1 & (2 + 3)) | (4 * 5); + int e = 1 & 2 + 3 | 4 * 5; + + int e_negative = (1 & (2 + 3)) | (4 * 5); // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int f = (1 * -2) + 4; + int f = 1 * -2 + 4; + + int f_negative = (1 * -2) + 4; // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int g = (1 * 2 * 3) + 4 + 5; + int g = 1 * 2 * 3 + 4 + 5; + + int g_negative = (1 * 2 * 3) + 4 + 5; // No warning + + //CHECK-MESSAGES: :[[@LINE+4]]:13: warning: '&' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+3]]:19: warning: '+' has higher precedence than '&'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+2]]:27: warning: '*' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int h = (120 & (2 + 3)) | (22 * 5); + int h = 120 & 2 + 3 | 22 * 5; + + int h_negative = (120 & (2 + 3)) | (22 * 5); // No warning + + int i = 1 & 2 & 3; // No warning + + int j = 1 | 2 | 3; // No warning + + int k = 1 ^ 2 ^ 3; // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:13: warning: '+' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int l = (1 + 2) ^ 3; + int l = 1 + 2 ^ 3; + + int l_negative = (1 + 2) ^ 3; // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int m = (2 * foo()) + bar(); + int m = 2 * foo() + bar(); + + int m_negative = (2 * foo()) + bar(); // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:13: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int n = (1.05 * foo()) + double(bar()); + int n = 1.05 * foo() + double(bar()); + + int n_negative = (1.05 * foo()) + double(bar()); // No warning + + //CHECK-MESSAGES: :[[@LINE+3]]:17: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int o = 1 + (obj.A * 3) + obj.B; + fun obj; + int o = 1 + obj.A * 3 + obj.B; + + int o_negative = 1 + (obj.A * 3) + obj.B; // No warning + + //CHECK-MESSAGES: :[[@LINE+2]]:18: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int p = 1U + (2 * 3); + int p = 1U + 2 * 3; + + int p_negative = 1U + (2 * 3); // No warning + + //CHECK-MESSAGES: :[[@LINE+7]]:13: warning: '+' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+6]]:25: warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+5]]:53: warning: '&' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+4]]:53: warning: '^' has higher precedence than '|'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+3]]:77: warning: '-' has higher precedence than '^'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-MESSAGES: :[[@LINE+2]]:94: warning: '/' has higher precedence than '-'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses] + //CHECK-FIXES: int q = (1 MACRO_ADD (2 MACRO_MULTIPLY 3)) MACRO_OR ((4 MACRO_AND 5) MACRO_XOR (6 MACRO_SUBTRACT (7 MACRO_DIVIDE 8))); + int q = 1 MACRO_ADD 2 MACRO_MULTIPLY 3 MACRO_OR 4 MACRO_AND 5 MACRO_XOR 6 MACRO_SUBTRACT 7 MACRO_DIVIDE 8; // No warning +} diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/5/.clang-tidy b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/5/.clang-tidy new file mode 100644 index 000000000000..e33f0f8bb332 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/config-files/5/.clang-tidy @@ -0,0 +1,4 @@ +InheritParentConfig: true +Checks: 'misc-throw-by-value-catch-by-reference' +CheckOptions: + misc-throw-by-value-catch-by-reference.MaxSize: '1152921504606846976' diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp index ab4f3becb7a9..cb0f0bc4d133 100644 --- a/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/config-files.cpp @@ -64,3 +64,11 @@ // Validate that check options are printed in alphabetical order: // RUN: clang-tidy --checks="-*,readability-identifier-naming" --dump-config %S/Inputs/config-files/- -- | grep "readability-identifier-naming\." | sort --check + +// Dumped config does not overflow for unsigned options +// RUN: clang-tidy --dump-config \ +// RUN: --checks="-*,misc-throw-by-value-catch-by-reference" \ +// RUN: -- | grep -v -q "misc-throw-by-value-catch-by-reference.MaxSize: '-1'" + +// RUN: clang-tidy --dump-config %S/Inputs/config-files/5/- \ +// RUN: -- | grep -q "misc-throw-by-value-catch-by-reference.MaxSize: '1152921504606846976'" diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp index f01ebd1ec67d..b16ec56e321b 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-general.cpp @@ -21,6 +21,12 @@ void foo() { // CHECK: --- // CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-general.cpp:3:1" // CHECK-NEXT: Introducer: PIK_HashPragma // CHECK-NEXT: - Callback: PragmaDiagnosticPush diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp index 932b0eb93c90..f5bf9ac2b955 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-ms.cpp @@ -18,6 +18,12 @@ // CHECK: --- // CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:3:1" // CHECK-NEXT: Introducer: PIK_HashPragma // CHECK-NEXT: - Callback: PragmaComment @@ -67,7 +73,7 @@ // CHECK-NEXT: Introducer: PIK_HashPragma // CHECK-NEXT: - Callback: PragmaMessage // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-ms.cpp:13:9" -// CHECK-NEXT: Namespace: +// CHECK-NEXT: Namespace: // CHECK-NEXT: Kind: PMK_Message // CHECK-NEXT: Str: message argument // CHECK-NEXT: - Callback: PragmaDirective diff --git a/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp b/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp index 31f61027994f..ed33d37eb3d5 100644 --- a/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp +++ b/clang-tools-extra/test/pp-trace/pp-trace-pragma-opencl.cpp @@ -6,6 +6,12 @@ // CHECK: --- // CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective +// CHECK-NEXT: Loc: ":{{.+}}:1" +// CHECK-NEXT: Introducer: PIK_HashPragma +// CHECK-NEXT: - Callback: PragmaDirective // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-pragma-opencl.cpp:3:1" // CHECK-NEXT: Introducer: PIK_HashPragma // CHECK-NEXT: - Callback: PragmaOpenCLExtension diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index f092766fa19f..cf97e3c6e851 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -166,6 +166,10 @@ if(CLANG_ENABLE_LIBXML2) endif() if(CLANG_ENABLE_CIR) + if (CLANG_BUILT_STANDALONE) + message(FATAL_ERROR + "ClangIR is not yet supported in the standalone build.") + endif() if (NOT "${LLVM_ENABLE_PROJECTS}" MATCHES "MLIR|mlir") message(FATAL_ERROR "Cannot build ClangIR without MLIR in LLVM_ENABLE_PROJECTS") diff --git a/clang/cmake/caches/Release.cmake b/clang/cmake/caches/Release.cmake index bd1f688d61a7..c0bfcbdfc1c2 100644 --- a/clang/cmake/caches/Release.cmake +++ b/clang/cmake/caches/Release.cmake @@ -1,93 +1,94 @@ # Plain options configure the first build. # BOOTSTRAP_* options configure the second build. # BOOTSTRAP_BOOTSTRAP_* options configure the third build. +# PGO Builds have 3 stages (stage1, stage2-instrumented, stage2) +# non-PGO Builds have 2 stages (stage1, stage2) -# General Options + +function (set_final_stage_var name value type) + if (LLVM_RELEASE_ENABLE_PGO) + set(BOOTSTRAP_BOOTSTRAP_${name} ${value} CACHE ${type} "") + else() + set(BOOTSTRAP_${name} ${value} CACHE ${type} "") + endif() +endfunction() + +function (set_instrument_and_final_stage_var name value type) + # This sets the varaible for the final stage in non-PGO builds and in + # the stage2-instrumented stage for PGO builds. + set(BOOTSTRAP_${name} ${value} CACHE ${type} "") + if (LLVM_RELEASE_ENABLE_PGO) + # Set the variable in the final stage for PGO builds. + set(BOOTSTRAP_BOOTSTRAP_${name} ${value} CACHE ${type} "") + endif() +endfunction() + +# General Options: +# If you want to override any of the LLVM_RELEASE_* variables you can set them +# on the command line via -D, but you need to do this before you pass this +# cache file to CMake via -C. e.g. +# +# cmake -D LLVM_RELEASE_ENABLE_PGO=ON -C Release.cmake set(LLVM_RELEASE_ENABLE_LTO THIN CACHE STRING "") set(LLVM_RELEASE_ENABLE_PGO OFF CACHE BOOL "") - +set(LLVM_RELEASE_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") +set(LLVM_RELEASE_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "") +# Note we don't need to add install here, since it is one of the pre-defined +# steps. +set(LLVM_RELEASE_FINAL_STAGE_TARGETS "clang;package;check-all;check-llvm;check-clang" CACHE STRING "") set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "") -# Stage 1 Bootstrap Setup +# Stage 1 Options +set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "") set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") + +set(STAGE1_PROJECTS "clang") +set(STAGE1_RUNTIMES "") + if (LLVM_RELEASE_ENABLE_PGO) + list(APPEND STAGE1_PROJECTS "lld") + list(APPEND STAGE1_RUNTIMES "compiler-rt") set(CLANG_BOOTSTRAP_TARGETS generate-profdata - stage2 + stage2-package stage2-clang - stage2-distribution stage2-install - stage2-install-distribution - stage2-install-distribution-toolchain stage2-check-all stage2-check-llvm - stage2-check-clang - stage2-test-suite CACHE STRING "") -else() - set(CLANG_BOOTSTRAP_TARGETS - clang - check-all - check-llvm - check-clang - test-suite - stage3 - stage3-clang - stage3-check-all - stage3-check-llvm - stage3-check-clang - stage3-install - stage3-test-suite CACHE STRING "") -endif() + stage2-check-clang CACHE STRING "") -# Stage 1 Options -set(STAGE1_PROJECTS "clang") -set(STAGE1_RUNTIMES "") + # Configuration for stage2-instrumented + set(BOOTSTRAP_CLANG_ENABLE_BOOTSTRAP ON CACHE STRING "") + # This enables the build targets for the final stage which is called stage2. + set(BOOTSTRAP_CLANG_BOOTSTRAP_TARGETS ${LLVM_RELEASE_FINAL_STAGE_TARGETS} CACHE STRING "") + set(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED IR CACHE STRING "") + set(BOOTSTRAP_LLVM_ENABLE_RUNTIMES "compiler-rt" CACHE STRING "") + set(BOOTSTRAP_LLVM_ENABLE_PROJECTS "clang;lld" CACHE STRING "") -if (LLVM_RELEASE_ENABLE_PGO) - list(APPEND STAGE1_PROJECTS "lld") - list(APPEND STAGE1_RUNTIMES "compiler-rt") +else() + if (LLVM_RELEASE_ENABLE_LTO) + list(APPEND STAGE1_PROJECTS "lld") + endif() + # Any targets added here will be given the target name stage2-${target}, so + # if you want to run them you can just use: + # ninja -C $BUILDDIR stage2-${target} + set(CLANG_BOOTSTRAP_TARGETS ${LLVM_RELEASE_FINAL_STAGE_TARGETS} CACHE STRING "") endif() +# Stage 1 Common Config set(LLVM_ENABLE_RUNTIMES ${STAGE1_RUNTIMES} CACHE STRING "") set(LLVM_ENABLE_PROJECTS ${STAGE1_PROJECTS} CACHE STRING "") -set(LLVM_TARGETS_TO_BUILD Native CACHE STRING "") - -# Stage 2 Bootstrap Setup -set(BOOTSTRAP_CLANG_ENABLE_BOOTSTRAP ON CACHE STRING "") -set(BOOTSTRAP_CLANG_BOOTSTRAP_TARGETS - clang - check-all - check-llvm - check-clang CACHE STRING "") - -# Stage 2 Options -set(STAGE2_PROJECTS "clang") -set(STAGE2_RUNTIMES "") - -if (LLVM_RELEASE_ENABLE_LTO OR LLVM_RELEASE_ENABLE_PGO) - list(APPEND STAGE2_PROJECTS "lld") -endif() - -if (LLVM_RELEASE_ENABLE_PGO) - set(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED IR CACHE STRING "") - list(APPEND STAGE2_RUNTIMES "compiler-rt") - set(BOOTSTRAP_LLVM_ENABLE_LTO ${LLVM_RELEASE_ENABLE_LTO}) - if (LLVM_RELEASE_ENABLE_LTO) - set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "") - endif() +# stage2-instrumented and Final Stage Config: +# Options that need to be set in both the instrumented stage (if we are doing +# a pgo build) and the final stage. +set_instrument_and_final_stage_var(CMAKE_POSITION_INDEPENDENT_CODE "ON" STRING) +set_instrument_and_final_stage_var(LLVM_ENABLE_LTO "${LLVM_RELEASE_ENABLE_LTO}" STRING) +if (LLVM_RELEASE_ENABLE_LTO) + set_instrument_and_final_stage_var(LLVM_ENABLE_LLD "ON" BOOL) endif() -set(BOOTSTRAP_LLVM_ENABLE_PROJECTS ${STAGE2_PROJECTS} CACHE STRING "") -set(BOOTSTRAP_LLVM_ENABLE_RUNTIMES ${STAGE2_RUNTIMES} CACHE STRING "") -if (NOT LLVM_RELEASE_ENABLE_PGO) - set(BOOTSTRAP_LLVM_TARGETS_TO_BUILD Native CACHE STRING "") -endif() +# Final Stage Config (stage2) +set_final_stage_var(LLVM_ENABLE_RUNTIMES "${LLVM_RELEASE_ENABLE_RUNTIMES}" STRING) +set_final_stage_var(LLVM_ENABLE_PROJECTS "${LLVM_RELEASE_ENABLE_PROJECTS}" STRING) -# Stage 3 Options -set(BOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_RUNTIMES "compiler-rt;libcxx;libcxxabi;libunwind" CACHE STRING "") -set(BOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_PROJECTS "clang;lld;lldb;clang-tools-extra;bolt;polly;mlir;flang" CACHE STRING "") -set(BOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_LTO ${LLVM_RELEASE_ENABLE_LTO} CACHE STRING "") -if (LLVM_RELEASE_ENABLE_LTO) - set(BOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "") -endif() diff --git a/clang/cmake/caches/VectorEngine.cmake b/clang/cmake/caches/VectorEngine.cmake index e3976f3206db..2f968a21cc40 100644 --- a/clang/cmake/caches/VectorEngine.cmake +++ b/clang/cmake/caches/VectorEngine.cmake @@ -40,6 +40,7 @@ set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_CRT OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") +set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_CTX_PROFILE OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_PROFILE OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") set(RUNTIMES_x86_64-unknown-linux-gnu_COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") @@ -52,6 +53,7 @@ set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_SANITIZERS OFF CACHE BOOL "" set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_XRAY OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_LIBFUZZER OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_PROFILE ON CACHE BOOL "") +set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_CTX_PROFILE OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_MEMPROF OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_ORC OFF CACHE BOOL "") set(RUNTIMES_ve-unknown-linux-gnu_COMPILER_RT_BUILD_GWP_ASAN OFF CACHE BOOL "") diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 84fc4dee02fa..c2e90f4e7d58 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -711,6 +711,8 @@ even-odd element pair with indices ``i * 2`` and ``i * 2 + 1`` with power of 2, the vector is widened with neutral elements for the reduction at the end to the next power of 2. +These reductions support both fixed-sized and scalable vector types. + Example: .. code-block:: c++ @@ -1493,6 +1495,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+ ``if consteval`` __cpp_if_consteval C++23 C++20 ``static operator()`` __cpp_static_call_operator C++23 C++03 Attributes on Lambda-Expressions C++23 C++11 +Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03 ``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03 -------------------------------------------- -------------------------------- ------------- ------------- Designated initializers (N494) C99 C89 @@ -2928,7 +2931,7 @@ Query for this feature with ``__has_builtin(__builtin_dump_struct)`` ``__builtin_shufflevector`` is used to express generic vector permutation/shuffle/swizzle operations. This builtin is also very important for the implementation of various target-specific header files like -````. +````. This builtin can be used within constant expressions. **Syntax**: @@ -2955,7 +2958,7 @@ for the implementation of various target-specific header files like // Concatenate every other element of 8-element vectors V1 and V2. __builtin_shufflevector(V1, V2, 0, 2, 4, 6, 8, 10, 12, 14) - // Shuffle v1 with some elements being undefined + // Shuffle v1 with some elements being undefined. Not allowed in constexpr. __builtin_shufflevector(v1, v1, 3, -1, 1, -1) **Description**: @@ -2968,6 +2971,7 @@ starting with the first vector, continuing into the second vector. Thus, if ``vec1`` is a 4-element vector, index 5 would refer to the second element of ``vec2``. An index of -1 can be used to indicate that the corresponding element in the returned vector is a don't care and can be optimized by the backend. +Values of -1 are not supported in constant expressions. The result of ``__builtin_shufflevector`` is a vector with the same element type as ``vec1``/``vec2`` but that has an element count equal to the number of @@ -2982,7 +2986,8 @@ Query for this feature with ``__has_builtin(__builtin_shufflevector)``. ``__builtin_convertvector`` is used to express generic vector type-conversion operations. The input vector and the output vector -type must have the same number of elements. +type must have the same number of elements. This builtin can be used within +constant expressions. **Syntax**: @@ -5572,3 +5577,25 @@ but the expression has no runtime effects. Type- and value-dependent expressions are not supported yet. This facility is designed to aid with testing name lookup machinery. + +Predefined Macros +================= + +`__GCC_DESTRUCTIVE_SIZE` and `__GCC_CONSTRUCTIVE_SIZE` +------------------------------------------------------ +Specify the mimum offset between two objects to avoid false sharing and the +maximum size of contiguous memory to promote true sharing, respectively. These +macros are predefined in all C and C++ language modes, but can be redefined on +the command line with ``-D`` to specify different values as needed or can be +undefined on the command line with ``-U`` to disable support for the feature. + +**Note: the values the macros expand to are not guaranteed to be stable. They +are are affected by architectures and CPU tuning flags, can change between +releases of Clang and will not match the values defined by other compilers such +as GCC.** + +Compiling different TUs depending on these flags (including use of +``std::hardware_constructive_interference`` or +``std::hardware_destructive_interference``) with different compilers, macro +definitions, or architecture flags will lead to ODR violations and should be +avoided. \ No newline at end of file diff --git a/clang/docs/LibTooling.rst b/clang/docs/LibTooling.rst index df50dcebf9b8..87d84321ab28 100644 --- a/clang/docs/LibTooling.rst +++ b/clang/docs/LibTooling.rst @@ -63,15 +63,22 @@ and automatic location of the compilation database using source files paths. #include "llvm/Support/CommandLine.h" using namespace clang::tooling; + using namespace llvm; // Apply a custom category to all command-line options so that they are the // only ones displayed. - static llvm::cl::OptionCategory MyToolCategory("my-tool options"); + static cl::OptionCategory MyToolCategory("my-tool options"); int main(int argc, const char **argv) { - // CommonOptionsParser constructor will parse arguments and create a - // CompilationDatabase. In case of error it will terminate the program. - CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); + // CommonOptionsParser::create will parse arguments and create a + // CompilationDatabase. + auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory); + if (!ExpectedParser) { + // Fail gracefully for unsupported options. + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser& OptionsParser = ExpectedParser.get(); // Use OptionsParser.getCompilations() and OptionsParser.getSourcePathList() // to retrieve CompilationDatabase and the list of input file paths. @@ -133,7 +140,12 @@ version of this example tool is also checked into the clang tree at static cl::extrahelp MoreHelp("\nMore help text...\n"); int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); + auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser& OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return Tool.run(newFrontendActionFactory().get()); diff --git a/clang/docs/OpenMPSupport.rst b/clang/docs/OpenMPSupport.rst index f8146bc365e8..5e63b2c0f0be 100644 --- a/clang/docs/OpenMPSupport.rst +++ b/clang/docs/OpenMPSupport.rst @@ -310,7 +310,9 @@ implementation. +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | misc | dispatch construct and function variant argument adjustment | :part:`worked on` | D99537, D99679 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ -| misc | assume and assumes directives | :part:`worked on` | | +| misc | assumes directives | :part:`worked on` | | ++------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ +| misc | assume directive | :part:`worked on` | | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ | misc | nothing directive | :good:`done` | D123286 | +------------------------------+--------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------+ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f339fab6e842..2d0e663d93e4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -90,6 +90,18 @@ C++ Language Changes -------------------- - Implemented ``_BitInt`` literal suffixes ``__wb`` or ``__WB`` as a Clang extension with ``unsigned`` modifiers also allowed. (#GH85223). +C++17 Feature Support +^^^^^^^^^^^^^^^^^^^^^ +- Clang now exposes ``__GCC_DESTRUCTIVE_SIZE`` and ``__GCC_CONSTRUCTIVE_SIZE`` + predefined macros to support standard library implementations of + ``std::hardware_destructive_interference_size`` and + ``std::hardware_constructive_interference_size``, respectively. These macros + are predefined in all C and C++ language modes. The values the macros + expand to are not stable between releases of Clang and do not need to match + the values produced by GCC, so these macros should not be used from header + files because they may not be stable across multiple TUs (the values may vary + based on compiler version as well as CPU tuning). #GH60174 + C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ @@ -131,6 +143,9 @@ C++2c Feature Support - Implemented `P2573R2: = delete("should have a reason"); `_ +- Implemented `P0609R3: Attributes for Structured Bindings `_ + +- Implemented `P2748R5 Disallow Binding a Returned Glvalue to a Temporary `_. Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -207,6 +222,20 @@ Non-comprehensive list of changes in this release - ``__typeof_unqual__`` is available in all C modes as an extension, which behaves like ``typeof_unqual`` from C23, similar to ``__typeof__`` and ``typeof``. +- ``__builtin_reduce_{add|mul|xor|or|and|min|max}`` builtins now support scalable vectors. + +* Shared libraries linked with either the ``-ffast-math``, ``-Ofast``, or + ``-funsafe-math-optimizations`` flags will no longer enable flush-to-zero + floating-point mode by default. This decision can be overridden with use of + ``-mdaz-ftz``. This behavior now matches GCC's behavior. + (`#57589 `_) + +* ``-fdenormal-fp-math=preserve-sign`` is no longer implied by ``-ffast-math`` + on x86 systems. + +- Builtins ``__builtin_shufflevector()`` and ``__builtin_convertvector()`` may + now be used within constant expressions. + New Compiler Flags ------------------ - ``-fsanitize=implicit-bitfield-conversion`` checks implicit truncation and @@ -415,6 +444,9 @@ Bug Fixes in This Version operator. Fixes (#GH83267). +- Fix crash on ill-formed partial specialization with CRTP. + Fixes (#GH89374). + - Clang now correctly generates overloads for bit-precise integer types for builtin operators in C++. Fixes #GH82998. @@ -433,6 +465,10 @@ Bug Fixes in This Version - Fixed an assertion failure on invalid InitListExpr in C89 mode (#GH88008). +- Fixed missing destructor calls when we branch from middle of an expression. + This could happen through a branch in stmt-expr or in an expression containing a coroutine + suspension. Fixes (#GH63818) (#GH88478). + - Clang will no longer diagnose an erroneous non-dependent ``switch`` condition during instantiation, and instead will only diagnose it once, during checking of the function template. @@ -560,6 +596,11 @@ Bug Fixes to C++ Support - Fix the Itanium mangling of lambdas defined in a member of a local class (#GH88906) - Fixed a crash when trying to evaluate a user-defined ``static_assert`` message whose ``size()`` function returns a large or negative value. Fixes (#GH89407). +- Fixed a use-after-free bug in parsing of type constraints with default arguments that involve lambdas. (#GH67235) +- Fixed bug in which the body of a consteval lambda within a template was not parsed as within an + immediate function context. +- Fix CTAD for ``std::initializer_list``. This allows ``std::initializer_list{1, 2, 3}`` to be deduced as + ``std::initializer_list`` as intended. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -612,6 +653,9 @@ Arm and AArch64 Support * Arm Cortex-A78AE (cortex-a78ae). * Arm Cortex-A520AE (cortex-a520ae). * Arm Cortex-A720AE (cortex-a720ae). + * Arm Neoverse-N3 (neoverse-n3). + * Arm Neoverse-V3 (neoverse-v3). + * Arm Neoverse-V3AE (neoverse-v3ae). Android Support ^^^^^^^^^^^^^^^ @@ -706,6 +750,9 @@ clang-format libclang -------- +- ``clang_getSpellingLocation`` now correctly resolves macro expansions; that + is, it returns the spelling location instead of the expansion location. + Static Analyzer --------------- diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index c464bc3a69ad..a7fc7ec87a16 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1506,7 +1506,8 @@ floating point semantic models: precise (the default), strict, and fast. * ``-ffp-contract=fast`` - Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code. See + Note: ``-ffast-math`` causes ``crtfastmath.o`` to be linked with code unless + ``-shared`` or ``-mno-daz-ftz`` is present. See :ref:`crtfastmath.o` for more details. .. option:: -fno-fast-math @@ -1560,7 +1561,8 @@ floating point semantic models: precise (the default), strict, and fast. ``-ffp-contract``. Note: ``-fno-fast-math`` implies ``-fdenormal-fp-math=ieee``. - ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code. + ``-fno-fast-math`` causes ``crtfastmath.o`` to not be linked with code + unless ``-mdaz-ftz`` is present. .. option:: -fdenormal-fp-math= @@ -1938,10 +1940,13 @@ by using ``#pragma STDC FENV_ROUND`` with a value other than ``FE_DYNAMIC``. A note about ``crtfastmath.o`` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``-ffast-math`` and ``-funsafe-math-optimizations`` cause ``crtfastmath.o`` to be -automatically linked, which adds a static constructor that sets the FTZ/DAZ +``-ffast-math`` and ``-funsafe-math-optimizations`` without the ``-shared`` +option cause ``crtfastmath.o`` to be +automatically linked, which adds a static constructor that sets the FTZ/DAZ bits in MXCSR, affecting not only the current compilation unit but all static -and shared libraries included in the program. +and shared libraries included in the program. This decision can be overridden +by using either the flag ``-mdaz-ftz`` or ``-mno-daz-ftz`` to respectively +link or not link ``crtfastmath.o``. .. _FLT_EVAL_METHOD: @@ -2314,6 +2319,8 @@ are listed below. on ELF targets when using the integrated assembler. This flag currently only has an effect on ELF targets. +.. _funique_internal_linkage_names: + .. option:: -f[no]-unique-internal-linkage-names Controls whether Clang emits a unique (best-effort) symbol name for internal @@ -2443,27 +2450,41 @@ usual build cycle when using sample profilers for optimization: usual build flags that you always build your application with. The only requirement is that DWARF debug info including source line information is generated. This DWARF information is important for the profiler to be able - to map instructions back to source line locations. + to map instructions back to source line locations. The usefulness of this + DWARF information can be improved with the ``-fdebug-info-for-profiling`` + and ``-funique-internal-linkage-names`` options. - On Linux, ``-g`` or just ``-gline-tables-only`` is sufficient: + On Linux: .. code-block:: console - $ clang++ -O2 -gline-tables-only code.cc -o code + $ clang++ -O2 -gline-tables-only \ + -fdebug-info-for-profiling -funique-internal-linkage-names \ + code.cc -o code While MSVC-style targets default to CodeView debug information, DWARF debug information is required to generate source-level LLVM profiles. Use ``-gdwarf`` to include DWARF debug information: - .. code-block:: console + .. code-block:: winbatch + + > clang-cl /O2 -gdwarf -gline-tables-only ^ + /clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^ + code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf + +.. note:: - $ clang-cl -O2 -gdwarf -gline-tables-only coff-profile.cpp -fuse-ld=lld -link -debug:dwarf + :ref:`-funique-internal-linkage-names ` + generates unique names based on given command-line source file paths. If + your build system uses absolute source paths and these paths may change + between steps 1 and 4, then the uniqued function names may change and result + in unused profile data. Consider omitting this option in such cases. 2. Run the executable under a sampling profiler. The specific profiler you use does not really matter, as long as its output can be converted into the format that the LLVM optimizer understands. - Two such profilers are the the Linux Perf profiler + Two such profilers are the Linux Perf profiler (https://perf.wiki.kernel.org/) and Intel's Sampling Enabling Product (SEP), available as part of `Intel VTune `_. @@ -2477,7 +2498,9 @@ usual build cycle when using sample profilers for optimization: .. code-block:: console - $ perf record -b ./code + $ perf record -b -e BR_INST_RETIRED.NEAR_TAKEN:uppp ./code + + If the event above is unavailable, ``branches:u`` is probably next-best. Note the use of the ``-b`` flag. This tells Perf to use the Last Branch Record (LBR) to record call chains. While this is not strictly required, @@ -2527,21 +2550,42 @@ usual build cycle when using sample profilers for optimization: that executes faster than the original one. Note that you are not required to build the code with the exact same arguments that you used in the first step. The only requirement is that you build the code - with ``-gline-tables-only`` and ``-fprofile-sample-use``. + with the same debug info options and ``-fprofile-sample-use``. + + On Linux: .. code-block:: console - $ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof code.cc -o code + $ clang++ -O2 -gline-tables-only \ + -fdebug-info-for-profiling -funique-internal-linkage-names \ + -fprofile-sample-use=code.prof code.cc -o code - [OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/ - edge counters. The profile inference algorithm (profi) can be used to infer - missing blocks and edge counts, and improve the quality of profile data. - Enable it with ``-fsample-profile-use-profi``. + On Windows: - .. code-block:: console + .. code-block:: winbatch - $ clang++ -O2 -gline-tables-only -fprofile-sample-use=code.prof \ - -fsample-profile-use-profi code.cc -o code + > clang-cl /O2 -gdwarf -gline-tables-only ^ + /clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^ + /fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf + + [OPTIONAL] Sampling-based profiles can have inaccuracies or missing block/ + edge counters. The profile inference algorithm (profi) can be used to infer + missing blocks and edge counts, and improve the quality of profile data. + Enable it with ``-fsample-profile-use-profi``. For example, on Linux: + + .. code-block:: console + + $ clang++ -fsample-profile-use-profi -O2 -gline-tables-only \ + -fdebug-info-for-profiling -funique-internal-linkage-names \ + -fprofile-sample-use=code.prof code.cc -o code + + On Windows: + + .. code-block:: winbatch + + > clang-cl /clang:-fsample-profile-use-profi /O2 -gdwarf -gline-tables-only ^ + /clang:-fdebug-info-for-profiling /clang:-funique-internal-linkage-names ^ + /fprofile-sample-use=code.prof code.cc /Fe:code /fuse-ld=lld /link /debug:dwarf Sample Profile Formats """""""""""""""""""""" @@ -4921,6 +4965,9 @@ directory. Using the example installation above, this would mean passing If the user links the program with the ``clang`` or ``clang-cl`` drivers, the driver will pass this flag for them. +The auto-linking can be disabled with -fno-rtlib-defaultlib. If that flag is +used, pass the complete flag to required libraries as described for ASan below. + If the linker cannot find the appropriate library, it will emit an error like this:: diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 7a8bd985a91f..365b607c7411 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -1644,8 +1644,9 @@ enum CXCursorKind { CXCursor_ObjCSelfExpr = 146, /** OpenMP 5.0 [2.1.5, Array Section]. + * OpenACC 3.3 [2.7.1, Data Specification for Data Clauses (Sub Arrays)] */ - CXCursor_OMPArraySectionExpr = 147, + CXCursor_ArraySectionExpr = 147, /** Represents an @available(...) check. */ diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h index 93bb045d6a66..026a4a431e73 100644 --- a/clang/include/clang/APINotes/Types.h +++ b/clang/include/clang/APINotes/Types.h @@ -675,6 +675,11 @@ class TagInfo : public CommonTypeInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsFlagEnum : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned SwiftCopyableSpecified : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned SwiftCopyable : 1; + public: std::optional SwiftImportAs; std::optional SwiftRetainOp; @@ -682,7 +687,9 @@ public: std::optional EnumExtensibility; - TagInfo() : HasFlagEnum(0), IsFlagEnum(0) {} + TagInfo() + : HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false), + SwiftCopyable(false) {} std::optional isFlagEnum() const { if (HasFlagEnum) @@ -694,6 +701,15 @@ public: IsFlagEnum = Value.value_or(false); } + std::optional isSwiftCopyable() const { + return SwiftCopyableSpecified ? std::optional(SwiftCopyable) + : std::nullopt; + } + void setSwiftCopyable(std::optional Value) { + SwiftCopyableSpecified = Value.has_value(); + SwiftCopyable = Value.value_or(false); + } + TagInfo &operator|=(const TagInfo &RHS) { static_cast(*this) |= RHS; @@ -710,6 +726,9 @@ public: if (!EnumExtensibility) EnumExtensibility = RHS.EnumExtensibility; + if (!SwiftCopyableSpecified) + setSwiftCopyable(RHS.isSwiftCopyable()); + return *this; } @@ -724,6 +743,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) { LHS.SwiftRetainOp == RHS.SwiftRetainOp && LHS.SwiftReleaseOp == RHS.SwiftReleaseOp && LHS.isFlagEnum() == RHS.isFlagEnum() && + LHS.isSwiftCopyable() == RHS.isSwiftCopyable() && LHS.EnumExtensibility == RHS.EnumExtensibility; } diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 28f8d67811f0..6dbd06251dda 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -455,7 +455,7 @@ class ASTContext : public RefCountedBase { /// initialization of another module). struct PerModuleInitializers { llvm::SmallVector Initializers; - llvm::SmallVector LazyInitializers; + llvm::SmallVector LazyInitializers; void resolve(ASTContext &Ctx); }; @@ -1059,7 +1059,7 @@ public: /// or an ImportDecl nominating another module that has initializers. void addModuleInitializer(Module *M, Decl *Init); - void addLazyModuleInitializers(Module *M, ArrayRef IDs); + void addLazyModuleInitializers(Module *M, ArrayRef IDs); /// Get the initializations to perform when importing a module, if any. ArrayRef getModuleInitializers(Module *M); @@ -1127,7 +1127,8 @@ public: CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; CanQualType IncompleteMatrixIdxTy; - CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; + CanQualType ArraySectionTy; + CanQualType OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" @@ -2196,6 +2197,16 @@ public: return getQualifiedType(type.getUnqualifiedType(), Qs); } + /// \brief Return a type with the given __ptrauth qualifier. + QualType getPointerAuthType(QualType Ty, PointerAuthQualifier PointerAuth) { + assert(!Ty.getPointerAuth()); + assert(PointerAuth); + + Qualifiers Qs; + Qs.setPointerAuth(PointerAuth); + return getQualifiedType(Ty, Qs); + } + unsigned char getFixedPointScale(QualType Ty) const; unsigned char getFixedPointIBits(QualType Ty) const; llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const; diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 216dc9eef08b..bf7c204e4ad7 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -844,6 +844,12 @@ public: } } + void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *E) { + if (E->hasExplicitTemplateArgs()) + for (auto Arg : E->template_arguments()) + Visit(Arg.getArgument()); + } + void VisitRequiresExpr(const RequiresExpr *E) { for (auto *D : E->getLocalParameters()) Visit(D); diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 1f2797cc7014..ab036f1d445a 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -213,9 +213,9 @@ public: } Qualifiers readQualifiers() { - static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(Qualifiers().getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - uint32_t value = asImpl().readUInt32(); + uint64_t value = asImpl().readUInt64(); return Qualifiers::fromOpaqueValue(value); } diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h index 07afa388de2c..8e42fcaad1d3 100644 --- a/clang/include/clang/AST/AbstractBasicWriter.h +++ b/clang/include/clang/AST/AbstractBasicWriter.h @@ -196,9 +196,9 @@ public: } void writeQualifiers(Qualifiers value) { - static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint32_t), + static_assert(sizeof(value.getAsOpaqueValue()) <= sizeof(uint64_t), "update this if the value size changes"); - asImpl().writeUInt32(value.getAsOpaqueValue()); + asImpl().writeUInt64(value.getAsOpaqueValue()); } void writeExceptionSpecInfo( diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index c04f6f6f1271..0a36fdc5d9c0 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -320,7 +320,7 @@ PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy) // A placeholder type for OpenMP array sections. -PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) +PLACEHOLDER_TYPE(ArraySection, ArraySectionTy) // A placeholder type for OpenMP array shaping operation. PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h index 7abf9141237d..6d3a51c379f9 100644 --- a/clang/include/clang/AST/ComputeDependence.h +++ b/clang/include/clang/AST/ComputeDependence.h @@ -94,7 +94,7 @@ class DesignatedInitExpr; class ParenListExpr; class PseudoObjectExpr; class AtomicExpr; -class OMPArraySectionExpr; +class ArraySectionExpr; class OMPArrayShapingExpr; class OMPIteratorExpr; class ObjCArrayLiteral; @@ -189,7 +189,7 @@ ExprDependence computeDependence(ParenListExpr *E); ExprDependence computeDependence(PseudoObjectExpr *E); ExprDependence computeDependence(AtomicExpr *E); -ExprDependence computeDependence(OMPArraySectionExpr *E); +ExprDependence computeDependence(ArraySectionExpr *E); ExprDependence computeDependence(OMPArrayShapingExpr *E); ExprDependence computeDependence(OMPIteratorExpr *E); diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8b121896d66d..a53c27a99a8c 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -157,7 +157,7 @@ public: SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg); - static PragmaCommentDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned ArgSize); PragmaMSCommentKind getCommentKind() const { return CommentKind; } @@ -192,7 +192,7 @@ public: SourceLocation Loc, StringRef Name, StringRef Value); static PragmaDetectMismatchDecl * - CreateDeserialized(ASTContext &C, DeclID ID, unsigned NameValueSize); + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize); StringRef getName() const { return getTrailingObjects(); } StringRef getValue() const { return getTrailingObjects() + ValueStart; } @@ -518,7 +518,7 @@ public: static LabelDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); - static LabelDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LabelDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -581,7 +581,7 @@ public: IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested); - static NamespaceDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -1146,7 +1146,7 @@ public: const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - static VarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -1728,7 +1728,7 @@ public: static ImplicitParamDecl *Create(ASTContext &C, QualType T, ImplicitParamKind ParamKind); - static ImplicitParamDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ImplicitParamDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType Type, @@ -1782,7 +1782,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg); - static ParmVarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ParmVarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -2178,7 +2178,7 @@ public: bool hasWrittenPrototype, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause); - static FunctionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); @@ -3136,7 +3136,7 @@ public: TypeSourceInfo *TInfo, Expr *BW, bool Mutable, InClassInitStyle InitStyle); - static FieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. @@ -3311,7 +3311,7 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V); - static EnumConstantDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumConstantDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } @@ -3357,7 +3357,7 @@ public: QualType T, llvm::MutableArrayRef CH); - static IndirectFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static IndirectFieldDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using chain_iterator = ArrayRef::const_iterator; @@ -3542,7 +3542,7 @@ public: static TypedefDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypedefDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypedefDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3567,7 +3567,7 @@ public: static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo); - static TypeAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3977,7 +3977,7 @@ public: IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed); - static EnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Overrides to provide correct range when there's an enum-base specifier /// with forward declarations. @@ -4182,7 +4182,7 @@ public: static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr); - static RecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static RecordDecl *CreateDeserialized(const ASTContext &C, GlobalDeclID ID); RecordDecl *getPreviousDecl() { return cast_or_null( @@ -4433,7 +4433,7 @@ public: StringLiteral *Str, SourceLocation AsmLoc, SourceLocation RParenLoc); - static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4469,7 +4469,7 @@ class TopLevelStmtDecl : public Decl, public DeclContext { public: static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement); - static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; Stmt *getStmt() { return Statement; } @@ -4563,7 +4563,7 @@ protected: public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static BlockDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BlockDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getCaretLocation() const { return getLocation(); } @@ -4717,7 +4717,7 @@ public: static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams); - static CapturedDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CapturedDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams); Stmt *getBody() const override; @@ -4851,7 +4851,7 @@ public: SourceLocation EndLoc); /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static ImportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. @@ -4892,7 +4892,7 @@ private: public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); - static ExportDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ExportDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } @@ -4931,7 +4931,7 @@ class EmptyDecl : public Decl { public: static EmptyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); - static EmptyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static EmptyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Empty; } @@ -4957,7 +4957,7 @@ public: bool CBuffer, SourceLocation KwLoc, IdentifierInfo *ID, SourceLocation IDLoc, SourceLocation LBrace); - static HLSLBufferDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static HLSLBufferDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(getLocStart(), RBraceLoc); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 161e14fc8969..e43e812cd945 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -15,6 +15,7 @@ #include "clang/AST/ASTDumperUtils.h" #include "clang/AST/AttrIterator.h" +#include "clang/AST/DeclID.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/SelectorLocationsKind.h" #include "clang/Basic/IdentifierTable.h" @@ -349,8 +350,6 @@ protected: LLVM_PREFERRED_TYPE(Linkage) mutable unsigned CacheValidAndLinkage : 3; - using DeclID = uint32_t; - /// Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is @@ -360,7 +359,7 @@ protected: /// \param Ctx The context in which we will allocate memory. /// \param ID The global ID of the deserialized declaration. /// \param Extra The amount of extra space to allocate after the object. - void *operator new(std::size_t Size, const ASTContext &Ctx, DeclID ID, + void *operator new(std::size_t Size, const ASTContext &Ctx, GlobalDeclID ID, std::size_t Extra = 0); /// Allocate memory for a non-deserialized declaration. @@ -778,10 +777,10 @@ public: /// Retrieve the global declaration ID associated with this /// declaration, which specifies where this Decl was loaded from. - unsigned getGlobalID() const { + GlobalDeclID getGlobalID() const { if (isFromASTFile()) - return *((const unsigned*)this - 1); - return 0; + return (*((const GlobalDeclID *)this - 1)); + return GlobalDeclID(); } /// Retrieve the global ID of the module that owns this particular diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index a7644d2a19d2..fb52ac804849 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -120,7 +120,7 @@ public: return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc); } - static AccessSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static AccessSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -579,7 +579,8 @@ public: TypeSourceInfo *Info, SourceLocation Loc, unsigned DependencyKind, bool IsGeneric, LambdaCaptureDefault CaptureDefault); - static CXXRecordDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static CXXRecordDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); bool isDynamicClass() const { return data().Polymorphic || data().NumVBases != 0; @@ -1980,7 +1981,8 @@ public: CXXConstructorDecl *Ctor = nullptr, DeductionCandidate Kind = DeductionCandidate::Normal); - static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return ExplicitSpec; } const ExplicitSpecifier getExplicitSpecifier() const { return ExplicitSpec; } @@ -2035,7 +2037,8 @@ public: static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc); - static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2078,7 +2081,7 @@ public: ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); bool isStatic() const; bool isInstance() const { return !isStatic(); } @@ -2579,7 +2582,7 @@ public: friend class ASTDeclWriter; friend TrailingObjects; - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, uint64_t AllocKind); static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, @@ -2822,7 +2825,7 @@ public: bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, Expr *TrailingRequiresClause = nullptr); - static CXXDestructorDecl *CreateDeserialized(ASTContext & C, DeclID ID); + static CXXDestructorDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2881,7 +2884,7 @@ public: bool UsesFPIntrin, bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, Expr *TrailingRequiresClause = nullptr); - static CXXConversionDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static CXXConversionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->ExplicitSpec; @@ -2948,7 +2951,7 @@ public: SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces); - static LinkageSpecDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static LinkageSpecDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the language specified by this linkage specification. LinkageSpecLanguageIDs getLanguage() const { @@ -3096,7 +3099,7 @@ public: SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor); - static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(UsingLoc, getLocation()); @@ -3157,7 +3160,7 @@ public: SourceLocation IdentLoc, NamedDecl *Namespace); - static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3254,7 +3257,7 @@ public: LifetimeExtendedTemporaryDecl(Temp, EDec, Mangling); } static LifetimeExtendedTemporaryDecl *CreateDeserialized(ASTContext &C, - DeclID ID) { + GlobalDeclID ID) { return new (C, ID) LifetimeExtendedTemporaryDecl(EmptyShell{}); } @@ -3357,7 +3360,7 @@ public: UsingShadowDecl(UsingShadow, C, DC, Loc, Name, Introducer, Target); } - static UsingShadowDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingShadowDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -3566,7 +3569,7 @@ public: const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword); - static UsingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3645,7 +3648,7 @@ public: UsingDecl *Using, NamedDecl *Target, bool IsVirtual); static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Override the UsingShadowDecl's getIntroducer, returning the UsingDecl that /// introduced this. @@ -3757,7 +3760,7 @@ public: SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType); - static UsingEnumDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static UsingEnumDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -3830,7 +3833,7 @@ public: NamedDecl *InstantiatedFrom, ArrayRef UsingDecls); - static UsingPackDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static UsingPackDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); SourceRange getSourceRange() const override LLVM_READONLY { @@ -3923,8 +3926,8 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc); - static UnresolvedUsingValueDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingValueDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -4014,8 +4017,8 @@ public: SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc); - static UnresolvedUsingTypenameDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static UnresolvedUsingTypenameDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// Retrieves the canonical declaration of this declaration. UnresolvedUsingTypenameDecl *getCanonicalDecl() override { @@ -4045,7 +4048,7 @@ public: SourceLocation Loc, DeclarationName Name); static UnresolvedUsingIfExistsDecl *CreateDeserialized(ASTContext &Ctx, - DeclID ID); + GlobalDeclID ID); static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Decl::UnresolvedUsingIfExists; } @@ -4073,7 +4076,7 @@ public: SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed); - static StaticAssertDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static StaticAssertDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } @@ -4120,7 +4123,7 @@ public: static BindingDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id); - static BindingDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static BindingDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Get the expression to which this declaration is bound. This may be null /// in two different cases: while parsing the initializer for the @@ -4189,7 +4192,7 @@ public: QualType T, TypeSourceInfo *TInfo, StorageClass S, ArrayRef Bindings); - static DecompositionDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static DecompositionDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumBindings); ArrayRef bindings() const { @@ -4246,7 +4249,7 @@ public: SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter); - static MSPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); static bool classof(const Decl *D) { return D->getKind() == MSProperty; } @@ -4300,7 +4303,7 @@ private: MSGuidDecl(DeclContext *DC, QualType T, Parts P); static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); - static MSGuidDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static MSGuidDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); // Only ASTContext::getMSGuidDecl and deserialization create these. friend class ASTContext; @@ -4353,7 +4356,7 @@ class UnnamedGlobalConstantDecl : public ValueDecl, static UnnamedGlobalConstantDecl *Create(const ASTContext &C, QualType T, const APValue &APVal); static UnnamedGlobalConstantDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); // Only ASTContext::getUnnamedGlobalConstantDecl and deserialization create // these. diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index c4734ab57895..e169c4859219 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -42,11 +42,12 @@ class StoredDeclsList { /// external declarations. DeclsAndHasExternalTy Data; - template - void erase_if(Fn ShouldErase) { + template DeclListNode::Decls *erase_if(Fn ShouldErase) { Decls List = Data.getPointer(); + if (!List) - return; + return nullptr; + ASTContext &C = getASTContext(); DeclListNode::Decls NewHead = nullptr; DeclListNode::Decls *NewLast = nullptr; @@ -79,6 +80,17 @@ class StoredDeclsList { Data.setPointer(NewHead); assert(llvm::none_of(getLookupResult(), ShouldErase) && "Still exists!"); + + if (!Data.getPointer()) + // All declarations are erased. + return nullptr; + else if (NewHead.is()) + // The list only contains a declaration, the header itself. + return (DeclListNode::Decls *)&Data; + else { + assert(NewLast && NewLast->is() && "Not the tail?"); + return NewLast; + } } void erase(NamedDecl *ND) { @@ -160,12 +172,16 @@ public: void replaceExternalDecls(ArrayRef Decls) { // Remove all declarations that are either external or are replaced with - // external declarations. - erase_if([Decls](NamedDecl *ND) { + // external declarations with higher visibilities. + DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; + // FIXME: Can we get rid of this loop completely? for (NamedDecl *D : Decls) - if (D->declarationReplaces(ND, /*IsKnownNewer=*/false)) + // Only replace the local declaration if the external declaration has + // higher visibilities. + if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false)) return true; return false; }); @@ -185,24 +201,15 @@ public: DeclsAsList = Node; } - DeclListNode::Decls Head = Data.getPointer(); - if (Head.isNull()) { + if (!Data.getPointer()) { Data.setPointer(DeclsAsList); return; } - // Find the end of the existing list. - // FIXME: It would be possible to preserve information from erase_if to - // avoid this rescan looking for the end of the list. - DeclListNode::Decls *Tail = &Head; - while (DeclListNode *Node = Tail->dyn_cast()) - Tail = &Node->Rest; - // Append the Decls. DeclListNode *Node = C.AllocateDeclListNode(Tail->get()); Node->Rest = DeclsAsList; *Tail = Node; - Data.setPointer(Head); } /// Return the list of all the decls. diff --git a/clang/include/clang/AST/DeclFriend.h b/clang/include/clang/AST/DeclFriend.h index b56627a5337d..9789282f351a 100644 --- a/clang/include/clang/AST/DeclFriend.h +++ b/clang/include/clang/AST/DeclFriend.h @@ -112,7 +112,7 @@ public: Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, ArrayRef FriendTypeTPLists = std::nullopt); - static FriendDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly diff --git a/clang/include/clang/AST/DeclID.h b/clang/include/clang/AST/DeclID.h new file mode 100644 index 000000000000..614ba06b6386 --- /dev/null +++ b/clang/include/clang/AST/DeclID.h @@ -0,0 +1,227 @@ +//===--- DeclID.h - ID number for deserialized declarations ----*- 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 DeclID class family to describe the deserialized +// declarations. The DeclID is widely used in AST via LazyDeclPtr, or calls to +// `ExternalASTSource::getExternalDecl`. It will be helpful for type safety to +// require the use of `DeclID` to explicit. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLID_H +#define LLVM_CLANG_AST_DECLID_H + +#include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/iterator.h" + +namespace clang { + +/// Predefined declaration IDs. +/// +/// These declaration IDs correspond to predefined declarations in the AST +/// context, such as the NULL declaration ID. Such declarations are never +/// actually serialized, since they will be built by the AST context when +/// it is created. +enum PredefinedDeclIDs { + /// The NULL declaration. + PREDEF_DECL_NULL_ID = 0, + + /// The translation unit. + PREDEF_DECL_TRANSLATION_UNIT_ID = 1, + + /// The Objective-C 'id' type. + PREDEF_DECL_OBJC_ID_ID = 2, + + /// The Objective-C 'SEL' type. + PREDEF_DECL_OBJC_SEL_ID = 3, + + /// The Objective-C 'Class' type. + PREDEF_DECL_OBJC_CLASS_ID = 4, + + /// The Objective-C 'Protocol' type. + PREDEF_DECL_OBJC_PROTOCOL_ID = 5, + + /// The signed 128-bit integer type. + PREDEF_DECL_INT_128_ID = 6, + + /// The unsigned 128-bit integer type. + PREDEF_DECL_UNSIGNED_INT_128_ID = 7, + + /// The internal 'instancetype' typedef. + PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, + + /// The internal '__builtin_va_list' typedef. + PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + + /// The internal '__va_list_tag' struct, if any. + PREDEF_DECL_VA_LIST_TAG = 10, + + /// The internal '__builtin_ms_va_list' typedef. + PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + + /// The predeclared '_GUID' struct. + PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, + + /// The extern "C" context. + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, + + /// The internal '__make_integer_seq' template. + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, + + /// The internal '__NSConstantString' typedef. + PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, + + /// The internal '__NSConstantString' tag type. + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, + + /// The internal '__type_pack_element' template. + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, +}; + +/// The number of declaration IDs that are predefined. +/// +/// For more information about predefined declarations, see the +/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. +const unsigned int NUM_PREDEF_DECL_IDS = 18; + +/// GlobalDeclID means DeclID in the current ASTContext and LocalDeclID means +/// DeclID specific to a certain ModuleFile. Specially, in ASTWriter, the +/// LocalDeclID to the ModuleFile been writting is equal to the GlobalDeclID. +/// Outside the serializer, all the DeclID been used should be GlobalDeclID. +/// We can translate a LocalDeclID to the GlobalDeclID by +/// `ASTReader::getGlobalDeclID()`. + +class DeclIDBase { +public: + /// An ID number that refers to a declaration in an AST file. + /// + /// The ID numbers of declarations are consecutive (in order of + /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. + /// At the start of a chain of precompiled headers, declaration ID 1 is + /// used for the translation unit declaration. + /// + /// DeclID should only be used directly in serialization. All other users + /// should use LocalDeclID or GlobalDeclID. + using DeclID = uint32_t; + +protected: + DeclIDBase() : ID(PREDEF_DECL_NULL_ID) {} + explicit DeclIDBase(DeclID ID) : ID(ID) {} + +public: + DeclID get() const { return ID; } + + explicit operator DeclID() const { return ID; } + + explicit operator PredefinedDeclIDs() const { return (PredefinedDeclIDs)ID; } + + bool isValid() const { return ID != PREDEF_DECL_NULL_ID; } + + bool isInvalid() const { return ID == PREDEF_DECL_NULL_ID; } + + friend bool operator==(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID == RHS.ID; + } + friend bool operator!=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID != RHS.ID; + } + // We may sort the decl ID. + friend bool operator<(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID < RHS.ID; + } + friend bool operator>(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID > RHS.ID; + } + friend bool operator<=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID <= RHS.ID; + } + friend bool operator>=(const DeclIDBase &LHS, const DeclIDBase &RHS) { + return LHS.ID >= RHS.ID; + } + +protected: + DeclID ID; +}; + +class LocalDeclID : public DeclIDBase { + using Base = DeclIDBase; + +public: + LocalDeclID() : Base() {} + LocalDeclID(PredefinedDeclIDs ID) : Base(ID) {} + explicit LocalDeclID(DeclID ID) : Base(ID) {} + + LocalDeclID &operator++() { + ++ID; + return *this; + } + + LocalDeclID operator++(int) { + LocalDeclID Ret = *this; + ++(*this); + return Ret; + } +}; + +class GlobalDeclID : public DeclIDBase { + using Base = DeclIDBase; + +public: + GlobalDeclID() : Base() {} + explicit GlobalDeclID(DeclID ID) : Base(ID) {} + + // For DeclIDIterator to be able to convert a GlobalDeclID + // to a LocalDeclID. + explicit operator LocalDeclID() const { return LocalDeclID(this->ID); } +}; + +/// A helper iterator adaptor to convert the iterators to +/// `SmallVector` to the iterators to `SmallVector`. +template +class DeclIDIterator + : public llvm::iterator_adaptor_base, + const FromTy *, + std::forward_iterator_tag, ToTy> { +public: + DeclIDIterator() : DeclIDIterator::iterator_adaptor_base(nullptr) {} + + DeclIDIterator(const FromTy *ID) + : DeclIDIterator::iterator_adaptor_base(ID) {} + + ToTy operator*() const { return ToTy(*this->I); } + + bool operator==(const DeclIDIterator &RHS) const { return this->I == RHS.I; } +}; + +} // namespace clang + +namespace llvm { +template <> struct DenseMapInfo { + using GlobalDeclID = clang::GlobalDeclID; + using DeclID = GlobalDeclID::DeclID; + + static GlobalDeclID getEmptyKey() { + return GlobalDeclID(DenseMapInfo::getEmptyKey()); + } + + static GlobalDeclID getTombstoneKey() { + return GlobalDeclID(DenseMapInfo::getTombstoneKey()); + } + + static unsigned getHashValue(const GlobalDeclID &Key) { + return DenseMapInfo::getHashValue(Key.get()); + } + + static bool isEqual(const GlobalDeclID &L, const GlobalDeclID &R) { + return L == R; + } +}; + +} // namespace llvm + +#endif diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 7780afa6f1cf..d2cc61ca19f8 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -236,7 +236,7 @@ public: ObjCImplementationControl impControl = ObjCImplementationControl::None, bool HasRelatedResultType = false); - static ObjCMethodDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCMethodDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCMethodDecl *getCanonicalDecl() override; const ObjCMethodDecl *getCanonicalDecl() const { @@ -614,7 +614,8 @@ public: IdentifierInfo *name, SourceLocation colonLoc, TypeSourceInfo *boundInfo); - static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, DeclID ID); + static ObjCTypeParamDecl *CreateDeserialized(ASTContext &ctx, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -789,7 +790,7 @@ public: TypeSourceInfo *TSI, PropertyControl propControl = None); - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); SourceLocation getAtLoc() const { return AtLoc; } void setAtLoc(SourceLocation L) { AtLoc = L; } @@ -1279,7 +1280,8 @@ public: ObjCInterfaceDecl *PrevDecl, SourceLocation ClassLoc = SourceLocation(), bool isInternal = false); - static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, DeclID ID); + static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, + GlobalDeclID ID); /// Retrieve the type parameters of this class. /// @@ -1969,7 +1971,7 @@ public: TypeSourceInfo *TInfo, AccessControl ac, Expr *BW = nullptr, bool synthesized = false); - static ObjCIvarDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCIvarDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the @@ -2039,7 +2041,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, QualType T, Expr *BW); - static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2142,7 +2145,7 @@ public: SourceLocation atStartLoc, ObjCProtocolDecl *PrevDecl); - static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); const ObjCProtocolList &getReferencedProtocols() const { assert(hasDefinition() && "No definition available!"); @@ -2361,7 +2364,7 @@ public: ObjCTypeParamList *typeParamList, SourceLocation IvarLBraceLoc = SourceLocation(), SourceLocation IvarRBraceLoc = SourceLocation()); - static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); ObjCInterfaceDecl *getClassInterface() { return ClassInterface; } const ObjCInterfaceDecl *getClassInterface() const { return ClassInterface; } @@ -2558,7 +2561,8 @@ public: Create(ASTContext &C, DeclContext *DC, const IdentifierInfo *Id, ObjCInterfaceDecl *classInterface, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation CategoryNameLoc); - static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); ObjCCategoryDecl *getCategoryDecl() const; @@ -2640,7 +2644,8 @@ public: SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); - static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); /// init_iterator - Iterates through the ivar initializer list. using init_iterator = CXXCtorInitializer **; @@ -2780,7 +2785,7 @@ public: ObjCInterfaceDecl* aliasedClass); static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } @@ -2851,7 +2856,8 @@ public: ObjCIvarDecl *ivarDecl, SourceLocation ivarLoc); - static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index c7ede7f2157f..e542c3c8e66b 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -59,7 +59,7 @@ protected: } template - static T *createEmptyDirective(const ASTContext &C, unsigned ID, + static T *createEmptyDirective(const ASTContext &C, GlobalDeclID ID, unsigned NumClauses, unsigned NumChildren, Params &&... P) { auto *Inst = new (C, ID, size(NumClauses, NumChildren)) @@ -133,7 +133,7 @@ public: SourceLocation L, ArrayRef VL); static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, - DeclID ID, unsigned N); + GlobalDeclID ID, unsigned N); typedef MutableArrayRef::iterator varlist_iterator; typedef ArrayRef::iterator varlist_const_iterator; @@ -214,7 +214,7 @@ public: QualType T, OMPDeclareReductionDecl *PrevDeclInScope); /// Create deserialized declare reduction node. static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Get combiner expression of the declare reduction construct. Expr *getCombiner() { return Combiner; } @@ -318,8 +318,8 @@ public: ArrayRef Clauses, OMPDeclareMapperDecl *PrevDeclInScope); /// Creates deserialized declare mapper node. - static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, DeclID ID, - unsigned N); + static OMPDeclareMapperDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; using clauselist_const_iterator = ArrayRef::iterator; @@ -397,7 +397,8 @@ public: IdentifierInfo *Id, QualType T, SourceLocation StartLoc); - static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); SourceRange getSourceRange() const override LLVM_READONLY; @@ -427,7 +428,7 @@ public: static OMPRequiresDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef CL); /// Create deserialized requires node. - static OMPRequiresDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPRequiresDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned N); using clauselist_iterator = MutableArrayRef::iterator; @@ -495,7 +496,7 @@ public: static OMPAllocateDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef VL, ArrayRef CL); - static OMPAllocateDecl *CreateDeserialized(ASTContext &C, DeclID ID, + static OMPAllocateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NVars, unsigned NClauses); typedef MutableArrayRef::iterator varlist_iterator; diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e2afff8d4450..3ee03eebdb8c 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -797,7 +797,7 @@ protected: /// /// The first value in the array is the number of specializations/partial /// specializations that follow. - uint32_t *LazySpecializations = nullptr; + GlobalDeclID *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -1087,7 +1087,8 @@ public: NamedDecl *Decl); /// Create an empty function template node. - static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1204,9 +1205,9 @@ public: bool Typename, bool ParameterPack, bool HasTypeConstraint = false, std::optional NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID); + GlobalDeclID ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, - DeclID ID, + GlobalDeclID ID, bool HasTypeConstraint); /// Whether this template type parameter was declared with @@ -1413,11 +1414,10 @@ public: QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); + static NonTypeTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - bool HasTypeConstraint); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, + GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint); @@ -1632,10 +1632,9 @@ public: ArrayRef Expansions); static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID); - static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, - DeclID ID, - unsigned NumExpansions); + GlobalDeclID ID); + static TemplateTemplateParmDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1857,8 +1856,8 @@ public: ClassTemplateDecl *SpecializedTemplate, ArrayRef Args, ClassTemplateSpecializationDecl *PrevDecl); - static ClassTemplateSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2110,7 +2109,7 @@ public: ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * - CreateDeserialized(ASTContext &C, DeclID ID); + CreateDeserialized(ASTContext &C, GlobalDeclID ID); ClassTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -2306,7 +2305,7 @@ public: NamedDecl *Decl); /// Create an empty class template node. - static ClassTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ClassTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -2472,7 +2471,7 @@ public: MutableArrayRef Params, FriendUnion Friend, SourceLocation FriendLoc); - static FriendTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// If this friend declaration names a templated type (or /// a dependent member type of a templated type), return that @@ -2573,7 +2572,8 @@ public: NamedDecl *Decl); /// Create an empty alias template node. - static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, + GlobalDeclID ID); // Implement isa/cast/dyncast support static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2670,7 +2670,7 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override; @@ -2900,8 +2900,8 @@ public: TypeSourceInfo *TInfo, StorageClass S, ArrayRef Args, const TemplateArgumentListInfo &ArgInfos); - static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + static VarTemplatePartialSpecializationDecl * + CreateDeserialized(ASTContext &C, GlobalDeclID ID); VarTemplatePartialSpecializationDecl *getMostRecentDecl() { return cast( @@ -3078,7 +3078,7 @@ public: VarDecl *Decl); /// Create an empty variable template node. - static VarTemplateDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static VarTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); /// Return the specialization with the provided arguments if it exists, /// otherwise return the insertion point. @@ -3183,7 +3183,7 @@ public: SourceLocation L, DeclarationName Name, TemplateParameterList *Params, Expr *ConstraintExpr); - static ConceptDecl *CreateDeserialized(ASTContext &C, DeclID ID); + static ConceptDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID); Expr *getConstraintExpr() const { return ConstraintExpr; @@ -3232,7 +3232,7 @@ public: Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, ArrayRef ConvertedArgs); static ImplicitConceptSpecializationDecl * - CreateDeserialized(const ASTContext &C, DeclID ID, + CreateDeserialized(const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs); ArrayRef getTemplateArguments() const { @@ -3275,7 +3275,7 @@ private: static TemplateParamObjectDecl *Create(const ASTContext &C, QualType T, const APValue &V); static TemplateParamObjectDecl *CreateDeserialized(ASTContext &C, - DeclID ID); + GlobalDeclID ID); /// Only ASTContext::getTemplateParamObjectDecl and deserialization /// create these. diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 2bfefeabc348..f2bf667636dc 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -6610,6 +6610,275 @@ public: }; +/// This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', +/// with a boolean differentiator. +/// OpenMP 5.0 [2.1.5, Array Sections]. +/// To specify an array section in an OpenMP construct, array subscript +/// expressions are extended with the following syntax: +/// \code +/// [ lower-bound : length : stride ] +/// [ lower-bound : length : ] +/// [ lower-bound : length ] +/// [ lower-bound : : stride ] +/// [ lower-bound : : ] +/// [ lower-bound : ] +/// [ : length : stride ] +/// [ : length : ] +/// [ : length ] +/// [ : : stride ] +/// [ : : ] +/// [ : ] +/// \endcode +/// The array section must be a subset of the original array. +/// Array sections are allowed on multidimensional arrays. Base language array +/// subscript expressions can be used to specify length-one dimensions of +/// multidimensional array sections. +/// Each of the lower-bound, length, and stride expressions if specified must be +/// an integral type expressions of the base language. When evaluated +/// they represent a set of integer values as follows: +/// \code +/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , +/// lower-bound + ((length - 1) * stride) } +/// \endcode +/// The lower-bound and length must evaluate to non-negative integers. +/// The stride must evaluate to a positive integer. +/// When the size of the array dimension is not known, the length must be +/// specified explicitly. +/// When the stride is absent it defaults to 1. +/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, +/// where size is the size of the array dimension. When the lower-bound is +/// absent it defaults to 0. +/// +/// +/// OpenACC 3.3 [2.7.1 Data Specification in Data Clauses] +/// In C and C++, a subarray is an array name followed by an extended array +/// range specification in brackets, with start and length, such as +/// +/// AA[2:n] +/// +/// If the lower bound is missing, zero is used. If the length is missing and +/// the array has known size, the size of the array is used; otherwise the +/// length is required. The subarray AA[2:n] means elements AA[2], AA[3], . . . +/// , AA[2+n-1]. In C and C++, a two dimensional array may be declared in at +/// least four ways: +/// +/// -Statically-sized array: float AA[100][200]; +/// -Pointer to statically sized rows: typedef float row[200]; row* BB; +/// -Statically-sized array of pointers: float* CC[200]; +/// -Pointer to pointers: float** DD; +/// +/// Each dimension may be statically sized, or a pointer to dynamically +/// allocated memory. Each of these may be included in a data clause using +/// subarray notation to specify a rectangular array: +/// +/// -AA[2:n][0:200] +/// -BB[2:n][0:m] +/// -CC[2:n][0:m] +/// -DD[2:n][0:m] +/// +/// Multidimensional rectangular subarrays in C and C++ may be specified for any +/// array with any combination of statically-sized or dynamically-allocated +/// dimensions. For statically sized dimensions, all dimensions except the first +/// must specify the whole extent to preserve the contiguous data restriction, +/// discussed below. For dynamically allocated dimensions, the implementation +/// will allocate pointers in device memory corresponding to the pointers in +/// local memory and will fill in those pointers as appropriate. +/// +/// In Fortran, a subarray is an array name followed by a comma-separated list +/// of range specifications in parentheses, with lower and upper bound +/// subscripts, such as +/// +/// arr(1:high,low:100) +/// +/// If either the lower or upper bounds are missing, the declared or allocated +/// bounds of the array, if known, are used. All dimensions except the last must +/// specify the whole extent, to preserve the contiguous data restriction, +/// discussed below. +/// +/// Restrictions +/// +/// -In Fortran, the upper bound for the last dimension of an assumed-size dummy +/// array must be specified. +/// +/// -In C and C++, the length for dynamically allocated dimensions of an array +/// must be explicitly specified. +/// +/// -In C and C++, modifying pointers in pointer arrays during the data +/// lifetime, either on the host or on the device, may result in undefined +/// behavior. +/// +/// -If a subarray appears in a data clause, the implementation may choose to +/// allocate memory for only that subarray on the accelerator. +/// +/// -In Fortran, array pointers may appear, but pointer association is not +/// preserved in device memory. +/// +/// -Any array or subarray in a data clause, including Fortran array pointers, +/// must be a contiguous section of memory, except for dynamic multidimensional +/// C arrays. +/// +/// -In C and C++, if a variable or array of composite type appears, all the +/// data members of the struct or class are allocated and copied, as +/// appropriate. If a composite member is a pointer type, the data addressed by +/// that pointer are not implicitly copied. +/// +/// -In Fortran, if a variable or array of composite type appears, all the +/// members of that derived type are allocated and copied, as appropriate. If +/// any member has the allocatable or pointer attribute, the data accessed +/// through that member are not copied. +/// +/// -If an expression is used in a subscript or subarray expression in a clause +/// on a data construct, the same value is used when copying data at the end of +/// the data region, even if the values of variables in the expression change +/// during the data region. +class ArraySectionExpr : public Expr { + friend class ASTStmtReader; + friend class ASTStmtWriter; + +public: + enum ArraySectionType { OMPArraySection, OpenACCArraySection }; + +private: + enum { + BASE, + LOWER_BOUND, + LENGTH, + STRIDE, + END_EXPR, + OPENACC_END_EXPR = STRIDE + }; + + ArraySectionType ASType = OMPArraySection; + Stmt *SubExprs[END_EXPR] = {nullptr}; + SourceLocation ColonLocFirst; + SourceLocation ColonLocSecond; + SourceLocation RBracketLoc; + +public: + // Constructor for OMP array sections, which include a 'stride'. + ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, + QualType Type, ExprValueKind VK, ExprObjectKind OK, + SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, + SourceLocation RBracketLoc) + : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OMPArraySection), + ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), + RBracketLoc(RBracketLoc) { + setBase(Base); + setLowerBound(LowerBound); + setLength(Length); + setStride(Stride); + setDependence(computeDependence(this)); + } + + // Constructor for OpenACC sub-arrays, which do not permit a 'stride'. + ArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation ColonLoc, + SourceLocation RBracketLoc) + : Expr(ArraySectionExprClass, Type, VK, OK), ASType(OpenACCArraySection), + ColonLocFirst(ColonLoc), RBracketLoc(RBracketLoc) { + setBase(Base); + setLowerBound(LowerBound); + setLength(Length); + setDependence(computeDependence(this)); + } + + /// Create an empty array section expression. + explicit ArraySectionExpr(EmptyShell Shell) + : Expr(ArraySectionExprClass, Shell) {} + + /// Return original type of the base expression for array section. + static QualType getBaseOriginalType(const Expr *Base); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ArraySectionExprClass; + } + + bool isOMPArraySection() const { return ASType == OMPArraySection; } + bool isOpenACCArraySection() const { return ASType == OpenACCArraySection; } + + /// Get base of the array section. + Expr *getBase() { return cast(SubExprs[BASE]); } + const Expr *getBase() const { return cast(SubExprs[BASE]); } + + /// Get lower bound of array section. + Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } + const Expr *getLowerBound() const { + return cast_or_null(SubExprs[LOWER_BOUND]); + } + + /// Get length of array section. + Expr *getLength() { return cast_or_null(SubExprs[LENGTH]); } + const Expr *getLength() const { return cast_or_null(SubExprs[LENGTH]); } + + /// Get stride of array section. + Expr *getStride() { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + return cast_or_null(SubExprs[STRIDE]); + } + + const Expr *getStride() const { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + return cast_or_null(SubExprs[STRIDE]); + } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return getBase()->getBeginLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } + + SourceLocation getColonLocFirst() const { return ColonLocFirst; } + SourceLocation getColonLocSecond() const { + assert(ASType != OpenACCArraySection && + "second colon for stride not valid in OpenACC subarrays"); + return ColonLocSecond; + } + SourceLocation getRBracketLoc() const { return RBracketLoc; } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + child_range children() { + return child_range( + &SubExprs[BASE], + &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]); + } + + const_child_range children() const { + return const_child_range( + &SubExprs[BASE], + &SubExprs[ASType == OMPArraySection ? END_EXPR : OPENACC_END_EXPR]); + } + +private: + /// Set base of the array section. + void setBase(Expr *E) { SubExprs[BASE] = E; } + + /// Set lower bound of the array section. + void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; } + + /// Set length of the array section. + void setLength(Expr *E) { SubExprs[LENGTH] = E; } + + /// Set length of the array section. + void setStride(Expr *E) { + assert(ASType != OpenACCArraySection && + "Stride not valid in OpenACC subarrays"); + SubExprs[STRIDE] = E; + } + + void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } + + void setColonLocSecond(SourceLocation L) { + assert(ASType != OpenACCArraySection && + "second colon for stride not valid in OpenACC subarrays"); + ColonLocSecond = L; + } + void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } +}; + /// Frontend produces RecoveryExprs on semantic errors that prevent creating /// other well-formed expressions. E.g. when type-checking of a binary operator /// fails, we cannot produce a BinaryOperator expression. Instead, we can choose diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index be5b1f3fdd11..54a0c203f656 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -17,130 +17,6 @@ #include "clang/AST/Expr.h" namespace clang { -/// OpenMP 5.0 [2.1.5, Array Sections]. -/// To specify an array section in an OpenMP construct, array subscript -/// expressions are extended with the following syntax: -/// \code -/// [ lower-bound : length : stride ] -/// [ lower-bound : length : ] -/// [ lower-bound : length ] -/// [ lower-bound : : stride ] -/// [ lower-bound : : ] -/// [ lower-bound : ] -/// [ : length : stride ] -/// [ : length : ] -/// [ : length ] -/// [ : : stride ] -/// [ : : ] -/// [ : ] -/// \endcode -/// The array section must be a subset of the original array. -/// Array sections are allowed on multidimensional arrays. Base language array -/// subscript expressions can be used to specify length-one dimensions of -/// multidimensional array sections. -/// Each of the lower-bound, length, and stride expressions if specified must be -/// an integral type expressions of the base language. When evaluated -/// they represent a set of integer values as follows: -/// \code -/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , -/// lower-bound + ((length - 1) * stride) } -/// \endcode -/// The lower-bound and length must evaluate to non-negative integers. -/// The stride must evaluate to a positive integer. -/// When the size of the array dimension is not known, the length must be -/// specified explicitly. -/// When the stride is absent it defaults to 1. -/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, -/// where size is the size of the array dimension. When the lower-bound is -/// absent it defaults to 0. -class OMPArraySectionExpr : public Expr { - enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR }; - Stmt *SubExprs[END_EXPR]; - SourceLocation ColonLocFirst; - SourceLocation ColonLocSecond; - SourceLocation RBracketLoc; - -public: - OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, - QualType Type, ExprValueKind VK, ExprObjectKind OK, - SourceLocation ColonLocFirst, - SourceLocation ColonLocSecond, SourceLocation RBracketLoc) - : Expr(OMPArraySectionExprClass, Type, VK, OK), - ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), - RBracketLoc(RBracketLoc) { - SubExprs[BASE] = Base; - SubExprs[LOWER_BOUND] = LowerBound; - SubExprs[LENGTH] = Length; - SubExprs[STRIDE] = Stride; - setDependence(computeDependence(this)); - } - - /// Create an empty array section expression. - explicit OMPArraySectionExpr(EmptyShell Shell) - : Expr(OMPArraySectionExprClass, Shell) {} - - /// An array section can be written only as Base[LowerBound:Length]. - - /// Get base of the array section. - Expr *getBase() { return cast(SubExprs[BASE]); } - const Expr *getBase() const { return cast(SubExprs[BASE]); } - /// Set base of the array section. - void setBase(Expr *E) { SubExprs[BASE] = E; } - - /// Return original type of the base expression for array section. - static QualType getBaseOriginalType(const Expr *Base); - - /// Get lower bound of array section. - Expr *getLowerBound() { return cast_or_null(SubExprs[LOWER_BOUND]); } - const Expr *getLowerBound() const { - return cast_or_null(SubExprs[LOWER_BOUND]); - } - /// Set lower bound of the array section. - void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; } - - /// Get length of array section. - Expr *getLength() { return cast_or_null(SubExprs[LENGTH]); } - const Expr *getLength() const { return cast_or_null(SubExprs[LENGTH]); } - /// Set length of the array section. - void setLength(Expr *E) { SubExprs[LENGTH] = E; } - - /// Get stride of array section. - Expr *getStride() { return cast_or_null(SubExprs[STRIDE]); } - const Expr *getStride() const { return cast_or_null(SubExprs[STRIDE]); } - /// Set length of the array section. - void setStride(Expr *E) { SubExprs[STRIDE] = E; } - - SourceLocation getBeginLoc() const LLVM_READONLY { - return getBase()->getBeginLoc(); - } - SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } - - SourceLocation getColonLocFirst() const { return ColonLocFirst; } - void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } - - SourceLocation getColonLocSecond() const { return ColonLocSecond; } - void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; } - - SourceLocation getRBracketLoc() const { return RBracketLoc; } - void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } - - SourceLocation getExprLoc() const LLVM_READONLY { - return getBase()->getExprLoc(); - } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == OMPArraySectionExprClass; - } - - 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]); - } -}; - /// An explicit cast in C or a C-style cast in C++, which uses the syntax /// ([s1][s2]...[sn])expr. For example: @c ([3][3])f. class OMPArrayShapingExpr final diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 230c83943c22..385c32edbae0 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -99,7 +99,7 @@ public: /// passes back decl sets as VisibleDeclaration objects. /// /// The default implementation of this method is a no-op. - virtual Decl *GetExternalDecl(uint32_t ID); + virtual Decl *GetExternalDecl(GlobalDeclID ID); /// Resolve a selector ID into a selector. /// @@ -375,7 +375,7 @@ public: if (isOffset()) { assert(Source && "Cannot deserialize a lazy pointer without an AST source"); - Ptr = reinterpret_cast((Source->*Get)(Ptr >> 1)); + Ptr = reinterpret_cast((Source->*Get)(OffsT(Ptr >> 1))); } return reinterpret_cast(Ptr); } @@ -579,7 +579,7 @@ using LazyDeclStmtPtr = /// A lazy pointer to a declaration. using LazyDeclPtr = - LazyOffsetPtr; + LazyOffsetPtr; /// A lazy pointer to a set of CXXCtorInitializers. using LazyCXXCtorInitializersPtr = diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 7eb92e304a38..f9b145b4e86a 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2740,7 +2740,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {}) -DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) +DEF_TRAVERSE_STMT(ArraySectionExpr, {}) DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 99f45d518c79..e6643469e0b3 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -25,8 +25,10 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/PointerAuthOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" @@ -139,6 +141,174 @@ using CanQualType = CanQual; #define TYPE(Class, Base) class Class##Type; #include "clang/AST/TypeNodes.inc" +/// Pointer-authentication qualifiers. +class PointerAuthQualifier { + enum : uint32_t { + EnabledShift = 0, + EnabledBits = 1, + EnabledMask = 1 << EnabledShift, + AddressDiscriminatedShift = EnabledShift + EnabledBits, + AddressDiscriminatedBits = 1, + AddressDiscriminatedMask = 1 << AddressDiscriminatedShift, + AuthenticationModeShift = + AddressDiscriminatedShift + AddressDiscriminatedBits, + AuthenticationModeBits = 2, + AuthenticationModeMask = ((1 << AuthenticationModeBits) - 1) + << AuthenticationModeShift, + IsaPointerShift = AuthenticationModeShift + AuthenticationModeBits, + IsaPointerBits = 1, + IsaPointerMask = ((1 << IsaPointerBits) - 1) << IsaPointerShift, + AuthenticatesNullValuesShift = IsaPointerShift + IsaPointerBits, + AuthenticatesNullValuesBits = 1, + AuthenticatesNullValuesMask = ((1 << AuthenticatesNullValuesBits) - 1) + << AuthenticatesNullValuesShift, + KeyShift = AuthenticatesNullValuesShift + AuthenticatesNullValuesBits, + KeyBits = 10, + KeyMask = ((1 << KeyBits) - 1) << KeyShift, + DiscriminatorShift = KeyShift + KeyBits, + DiscriminatorBits = 16, + DiscriminatorMask = ((1u << DiscriminatorBits) - 1) << DiscriminatorShift, + }; + + // bits: |0 |1 |2..3 |4 | + // |Enabled|Address|AuthenticationMode|ISA pointer| + // bits: |5 |6..15| 16...31 | + // |AuthenticatesNull|Key |Discriminator| + uint32_t Data = 0; + + // The following static assertions check that each of the 32 bits is present + // exactly in one of the constants. + static_assert((EnabledBits + AddressDiscriminatedBits + + AuthenticationModeBits + IsaPointerBits + + AuthenticatesNullValuesBits + KeyBits + DiscriminatorBits) == + 32, + "PointerAuthQualifier should be exactly 32 bits"); + static_assert((EnabledMask + AddressDiscriminatedMask + + AuthenticationModeMask + IsaPointerMask + + AuthenticatesNullValuesMask + KeyMask + DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + static_assert((EnabledMask ^ AddressDiscriminatedMask ^ + AuthenticationModeMask ^ IsaPointerMask ^ + AuthenticatesNullValuesMask ^ KeyMask ^ DiscriminatorMask) == + 0xFFFFFFFF, + "All masks should cover the entire bits"); + + PointerAuthQualifier(unsigned Key, bool IsAddressDiscriminated, + unsigned ExtraDiscriminator, + PointerAuthenticationMode AuthenticationMode, + bool IsIsaPointer, bool AuthenticatesNullValues) + : Data(EnabledMask | + (IsAddressDiscriminated + ? llvm::to_underlying(AddressDiscriminatedMask) + : 0) | + (Key << KeyShift) | + (llvm::to_underlying(AuthenticationMode) + << AuthenticationModeShift) | + (ExtraDiscriminator << DiscriminatorShift) | + (IsIsaPointer << IsaPointerShift) | + (AuthenticatesNullValues << AuthenticatesNullValuesShift)) { + assert(Key <= KeyNoneInternal); + assert(ExtraDiscriminator <= MaxDiscriminator); + assert((Data == 0) == + (getAuthenticationMode() == PointerAuthenticationMode::None)); + } + +public: + enum { + KeyNoneInternal = (1u << KeyBits) - 1, + + /// The maximum supported pointer-authentication key. + MaxKey = KeyNoneInternal - 1, + + /// The maximum supported pointer-authentication discriminator. + MaxDiscriminator = (1u << DiscriminatorBits) - 1 + }; + +public: + PointerAuthQualifier() = default; + + static PointerAuthQualifier + Create(unsigned Key, bool IsAddressDiscriminated, unsigned ExtraDiscriminator, + PointerAuthenticationMode AuthenticationMode, bool IsIsaPointer, + bool AuthenticatesNullValues) { + if (Key == PointerAuthKeyNone) + Key = KeyNoneInternal; + assert(Key <= KeyNoneInternal && "out-of-range key value"); + return PointerAuthQualifier(Key, IsAddressDiscriminated, ExtraDiscriminator, + AuthenticationMode, IsIsaPointer, + AuthenticatesNullValues); + } + + bool isPresent() const { + assert((Data == 0) == + (getAuthenticationMode() == PointerAuthenticationMode::None)); + return Data != 0; + } + + explicit operator bool() const { return isPresent(); } + + unsigned getKey() const { + assert(isPresent()); + return (Data & KeyMask) >> KeyShift; + } + + bool hasKeyNone() const { return isPresent() && getKey() == KeyNoneInternal; } + + bool isAddressDiscriminated() const { + assert(isPresent()); + return (Data & AddressDiscriminatedMask) >> AddressDiscriminatedShift; + } + + unsigned getExtraDiscriminator() const { + assert(isPresent()); + return (Data >> DiscriminatorShift); + } + + PointerAuthenticationMode getAuthenticationMode() const { + return PointerAuthenticationMode((Data & AuthenticationModeMask) >> + AuthenticationModeShift); + } + + bool isIsaPointer() const { + assert(isPresent()); + return (Data & IsaPointerMask) >> IsaPointerShift; + } + + bool authenticatesNullValues() const { + assert(isPresent()); + return (Data & AuthenticatesNullValuesMask) >> AuthenticatesNullValuesShift; + } + + PointerAuthQualifier withoutKeyNone() const { + return hasKeyNone() ? PointerAuthQualifier() : *this; + } + + friend bool operator==(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data == Rhs.Data; + } + friend bool operator!=(PointerAuthQualifier Lhs, PointerAuthQualifier Rhs) { + return Lhs.Data != Rhs.Data; + } + + bool isEquivalent(PointerAuthQualifier Other) const { + return withoutKeyNone() == Other.withoutKeyNone(); + } + + uint32_t getAsOpaqueValue() const { return Data; } + + // Deserialize pointer-auth qualifiers from an opaque representation. + static PointerAuthQualifier fromOpaqueValue(uint32_t Opaque) { + PointerAuthQualifier Result; + Result.Data = Opaque; + assert((Result.Data == 0) == + (Result.getAuthenticationMode() == PointerAuthenticationMode::None)); + return Result; + } + + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Data); } +}; + /// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict @@ -147,8 +317,9 @@ using CanQualType = CanQual; /// * Objective C: the GC attributes (none, weak, or strong) class Qualifiers { public: - enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. - Const = 0x1, + enum TQ : uint64_t { + // NOTE: These flags must be kept in sync with DeclSpec::TQ. + Const = 0x1, Restrict = 0x2, Volatile = 0x4, CVRMask = Const | Volatile | Restrict @@ -182,7 +353,7 @@ public: OCL_Autoreleasing }; - enum { + enum : uint64_t { /// The maximum supported address space number. /// 23 bits should be enough for anyone. MaxAddressSpace = 0x7fffffu, @@ -197,16 +368,25 @@ public: /// Returns the common set of qualifiers while removing them from /// the given sets. static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { + Qualifiers Q; + PointerAuthQualifier LPtrAuth = L.getPointerAuth(); + if (LPtrAuth.isPresent() && + LPtrAuth.getKey() != PointerAuthQualifier::KeyNoneInternal && + LPtrAuth == R.getPointerAuth()) { + Q.setPointerAuth(LPtrAuth); + PointerAuthQualifier Empty; + L.setPointerAuth(Empty); + R.setPointerAuth(Empty); + } + // If both are only CVR-qualified, bit operations are sufficient. if (!(L.Mask & ~CVRMask) && !(R.Mask & ~CVRMask)) { - Qualifiers Q; Q.Mask = L.Mask & R.Mask; L.Mask &= ~Q.Mask; R.Mask &= ~Q.Mask; return Q; } - Qualifiers Q; unsigned CommonCRV = L.getCVRQualifiers() & R.getCVRQualifiers(); Q.addCVRQualifiers(CommonCRV); L.removeCVRQualifiers(CommonCRV); @@ -251,16 +431,14 @@ public: } // Deserialize qualifiers from an opaque representation. - static Qualifiers fromOpaqueValue(unsigned opaque) { + static Qualifiers fromOpaqueValue(uint64_t opaque) { Qualifiers Qs; Qs.Mask = opaque; return Qs; } // Serialize these qualifiers into an opaque representation. - unsigned getAsOpaqueValue() const { - return Mask; - } + uint64_t getAsOpaqueValue() const { return Mask; } bool hasConst() const { return Mask & Const; } bool hasOnlyConst() const { return Mask == Const; } @@ -302,7 +480,7 @@ public: } void removeCVRQualifiers(unsigned mask) { assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); - Mask &= ~mask; + Mask &= ~static_cast(mask); } void removeCVRQualifiers() { removeCVRQualifiers(CVRMask); @@ -407,6 +585,20 @@ public: setAddressSpace(space); } + bool hasPointerAuth() const { return Mask & PtrAuthMask; } + PointerAuthQualifier getPointerAuth() const { + return PointerAuthQualifier::fromOpaqueValue(Mask >> PtrAuthShift); + } + void setPointerAuth(PointerAuthQualifier Q) { + Mask = (Mask & ~PtrAuthMask) | + (uint64_t(Q.getAsOpaqueValue()) << PtrAuthShift); + } + void removePointerAuth() { Mask &= ~PtrAuthMask; } + void addPointerAuth(PointerAuthQualifier Q) { + assert(Q.isPresent()); + setPointerAuth(Q); + } + // Fast qualifiers are those that can be allocated directly // on a QualType object. bool hasFastQualifiers() const { return getFastQualifiers(); } @@ -417,7 +609,7 @@ public: } void removeFastQualifiers(unsigned mask) { assert(!(mask & ~FastMask) && "bitmask contains non-fast qualifier bits"); - Mask &= ~mask; + Mask &= ~static_cast(mask); } void removeFastQualifiers() { removeFastQualifiers(FastMask); @@ -454,6 +646,8 @@ public: addObjCGCAttr(Q.getObjCGCAttr()); if (Q.hasObjCLifetime()) addObjCLifetime(Q.getObjCLifetime()); + if (Q.hasPointerAuth()) + addPointerAuth(Q.getPointerAuth()); } } @@ -471,6 +665,8 @@ public: removeObjCLifetime(); if (getAddressSpace() == Q.getAddressSpace()) removeAddressSpace(); + if (getPointerAuth() == Q.getPointerAuth()) + removePointerAuth(); } } @@ -483,6 +679,8 @@ public: !hasObjCGCAttr() || !qs.hasObjCGCAttr()); assert(getObjCLifetime() == qs.getObjCLifetime() || !hasObjCLifetime() || !qs.hasObjCLifetime()); + assert(!hasPointerAuth() || !qs.hasPointerAuth() || + getPointerAuth() == qs.getPointerAuth()); Mask |= qs.Mask; } @@ -536,6 +734,8 @@ public: // be changed. (getObjCGCAttr() == other.getObjCGCAttr() || !hasObjCGCAttr() || !other.hasObjCGCAttr()) && + // Pointer-auth qualifiers must match exactly. + getPointerAuth() == other.getPointerAuth() && // ObjC lifetime qualifiers must match exactly. getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. @@ -605,24 +805,26 @@ public: void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty = false) const; - void Profile(llvm::FoldingSetNodeID &ID) const { - ID.AddInteger(Mask); - } + void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(Mask); } private: - // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| - // |C R V|U|GCAttr|Lifetime|AddressSpace| - uint32_t Mask = 0; - - static const uint32_t UMask = 0x8; - static const uint32_t UShift = 3; - static const uint32_t GCAttrMask = 0x30; - static const uint32_t GCAttrShift = 4; - static const uint32_t LifetimeMask = 0x1C0; - static const uint32_t LifetimeShift = 6; - static const uint32_t AddressSpaceMask = + // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31|32 ... 63| + // |C R V|U|GCAttr|Lifetime|AddressSpace| PtrAuth | + uint64_t Mask = 0; + static_assert(sizeof(PointerAuthQualifier) == sizeof(uint32_t), + "PointerAuthQualifier must be 32 bits"); + + static constexpr uint64_t UMask = 0x8; + static constexpr uint64_t UShift = 3; + static constexpr uint64_t GCAttrMask = 0x30; + static constexpr uint64_t GCAttrShift = 4; + static constexpr uint64_t LifetimeMask = 0x1C0; + static constexpr uint64_t LifetimeShift = 6; + static constexpr uint64_t AddressSpaceMask = ~(CVRMask | UMask | GCAttrMask | LifetimeMask); - static const uint32_t AddressSpaceShift = 9; + static constexpr uint64_t AddressSpaceShift = 9; + static constexpr uint64_t PtrAuthShift = 32; + static constexpr uint64_t PtrAuthMask = uint64_t(0xffffffff) << PtrAuthShift; }; class QualifiersAndAtomic { @@ -1242,6 +1444,10 @@ public: // true when Type is objc's weak and weak is enabled but ARC isn't. bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const; + PointerAuthQualifier getPointerAuth() const { + return getQualifiers().getPointerAuth(); + } + enum PrimitiveDefaultInitializeKind { /// The type does not fall into any of the following categories. Note that /// this case is zero-valued so that values of this enum can be used as a @@ -2172,6 +2378,10 @@ public: /// 'riscv_rvv_vector_bits' type attribute as VectorType. QualType getRVVEltType(const ASTContext &Ctx) const; + /// Returns the representative type for the element of a sizeless vector + /// builtin type. + QualType getSizelessVectorEltType(const ASTContext &Ctx) const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h index d50dba35f826..cdf89c7def2c 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h @@ -244,6 +244,21 @@ public: Environment::ValueModel &Model, ExprJoinBehavior ExprBehavior); + /// Returns a value that approximates both `Val1` and `Val2`, or null if no + /// such value can be produced. + /// + /// `Env1` and `Env2` can be used to query child values and path condition + /// implications of `Val1` and `Val2` respectively. The joined value will be + /// produced in `JoinedEnv`. + /// + /// Requirements: + /// + /// `Val1` and `Val2` must model values of type `Type`. + static Value *joinValues(QualType Ty, Value *Val1, const Environment &Env1, + Value *Val2, const Environment &Env2, + Environment &JoinedEnv, + Environment::ValueModel &Model); + /// Widens the environment point-wise, using `PrevEnv` as needed to inform the /// approximation. /// diff --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h b/clang/include/clang/Analysis/FlowSensitive/Transfer.h index ed148250d8eb..940025e02100 100644 --- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h +++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h @@ -53,7 +53,8 @@ private: /// Requirements: /// /// `S` must not be `ParenExpr` or `ExprWithCleanups`. -void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env); +void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, + Environment::ValueModel &Model); } // namespace dataflow } // namespace clang diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index dc87a8c6f022..97e06fe7d2e6 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -368,8 +368,8 @@ class Clang bit AllowInC = allowInC; } -// HLSL Semantic spellings -class HLSLSemantic : Spelling; +// HLSL Annotation spellings +class HLSLAnnotation : Spelling; class Accessor spellings> { string Name = name; @@ -3211,7 +3211,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr { def Unused : InheritableAttr { let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">, C23<"", "maybe_unused", 202106>]; - let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, + let Subjects = SubjectList<[Var, Binding, ObjCIvar, Type, Enum, EnumConstant, Label, Field, ObjCMethod, FunctionLike]>; let Documentation = [WarnMaybeUnusedDocs]; } @@ -4358,14 +4358,14 @@ def HLSLNumThreads: InheritableAttr { } def HLSLSV_GroupIndex: HLSLAnnotationAttr { - let Spellings = [HLSLSemantic<"SV_GroupIndex">]; + let Spellings = [HLSLAnnotation<"SV_GroupIndex">]; let Subjects = SubjectList<[ParmVar, GlobalVar]>; let LangOpts = [HLSL]; let Documentation = [HLSLSV_GroupIndexDocs]; } def HLSLResourceBinding: InheritableAttr { - let Spellings = [HLSLSemantic<"register">]; + let Spellings = [HLSLAnnotation<"register">]; let Subjects = SubjectList<[HLSLBufferObj, ExternalGlobalVar]>; let LangOpts = [HLSL]; let Args = [StringArgument<"Slot">, StringArgument<"Space", 1>]; @@ -4373,7 +4373,7 @@ def HLSLResourceBinding: InheritableAttr { } def HLSLSV_DispatchThreadID: HLSLAnnotationAttr { - let Spellings = [HLSLSemantic<"SV_DispatchThreadID">]; + let Spellings = [HLSLAnnotation<"SV_DispatchThreadID">]; let Subjects = SubjectList<[ParmVar, Field]>; let LangOpts = [HLSL]; let Documentation = [HLSLSV_DispatchThreadIDDocs]; diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index ef2ddf525c98..5f024b4b5fd7 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -52,8 +52,8 @@ public: /// Context-sensitive version of a keyword attribute. AS_ContextSensitiveKeyword, - /// : - AS_HLSLSemantic, + /// : + AS_HLSLAnnotation, /// The attibute has no source code manifestation and is only created /// implicitly. @@ -120,7 +120,7 @@ public: } static Form Pragma() { return AS_Pragma; } static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; } - static Form HLSLSemantic() { return AS_HLSLSemantic; } + static Form HLSLAnnotation() { return AS_HLSLAnnotation; } static Form Implicit() { return AS_Implicit; } private: diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index 14b08d4927ec..fcffadacc8e6 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -370,4 +370,7 @@ def warn_missing_symbol_graph_dir : Warning< "Missing symbol graph output directory, defaulting to working directory">, InGroup; +def err_ast_action_on_llvm_ir : Error< + "cannot apply AST actions to LLVM IR file '%0'">, + DefaultFatal; } diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 38174cf3549f..fdffb35ea0d9 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -478,6 +478,15 @@ def ext_decomp_decl_empty : ExtWarn< "ISO C++17 does not allow a decomposition group to be empty">, InGroup>; +// C++26 structured bindings +def ext_decl_attrs_on_binding : ExtWarn< + "an attribute specifier sequence attached to a structured binding declaration " + "is a C++2c extension">, InGroup; +def warn_cxx23_compat_decl_attrs_on_binding : Warning< + "an attribute specifier sequence attached to a structured binding declaration " + "is incompatible with C++ standards before C++2c">, + InGroup, DefaultIgnore; + /// Objective-C parser diagnostics def err_expected_minus_or_plus : Error< "method type specifier must start with '-' or '+'">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 63e951daec74..f72d5c252b86 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3755,14 +3755,12 @@ def err_sme_definition_using_za_in_non_sme_target : Error< def err_sme_definition_using_zt0_in_non_sme2_target : Error< "function using ZT0 state requires 'sme2'">; def warn_sme_streaming_pass_return_vl_to_non_streaming : Warning< - "passing a VL-dependent argument to/from a function that has a different" - " streaming-mode. The streaming and non-streaming vector lengths may be" - " different">, + "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a function with a different" + " streaming-mode is undefined behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup, DefaultIgnore; def warn_sme_locally_streaming_has_vl_args_returns : Warning< - "passing/returning a VL-dependent argument to/from a __arm_locally_streaming" - " function. The streaming and non-streaming vector" - " lengths may be different">, + "%select{returning|passing}0 a VL-dependent argument %select{from|to}0 a locally streaming function is undefined" + " behaviour when the streaming and non-streaming vector lengths are different at runtime">, InGroup, DefaultIgnore; def err_conflicting_attributes_arm_state : Error< "conflicting attributes for state '%0'">; @@ -9903,6 +9901,9 @@ def warn_format_invalid_annotation : Warning< def warn_format_P_no_precision : Warning< "using '%%P' format specifier without precision">, InGroup; +def warn_format_P_with_objc_pointer : Warning< + "using '%%P' format specifier with an Objective-C pointer results in dumping runtime object structure, not object value">, + InGroup; def warn_printf_ignored_flag: Warning< "flag '%0' is ignored when flag '%1' is present">, InGroup; @@ -9952,6 +9953,8 @@ def warn_ret_stack_addr_ref : Warning< def warn_ret_local_temp_addr_ref : Warning< "returning %select{address of|reference to}0 local temporary object">, InGroup; +def err_ret_local_temp_ref : Error< + "returning reference to local temporary object">; def warn_ret_addr_label : Warning< "returning address of label, which is local">, InGroup; @@ -10330,9 +10333,13 @@ def err_shufflevector_nonconstant_argument : Error< def err_shufflevector_argument_too_large : Error< "index for __builtin_shufflevector must be less than the total number " "of vector elements">; +def err_shufflevector_minus_one_is_undefined_behavior_constexpr : Error< + "index for __builtin_shufflevector not within the bounds of the input vectors; index of -1 found at position %0 not permitted in a constexpr context.">; def err_convertvector_non_vector : Error< "first argument to __builtin_convertvector must be a vector">; +def err_convertvector_constexpr_unsupported_vector_cast : Error< + "unsupported vector cast from %0 to %1 in a constant expression.">; def err_builtin_non_vector_type : Error< "%0 argument to %1 must be of vector type">; def err_convertvector_incompatible_vector : Error< @@ -11163,7 +11170,7 @@ 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_array_section_use : Error<"%select{OpenACC sub-array|OpenMP array section}0 is not allowed here">; def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; def err_omp_iterator_use : Error<"OpenMP iterator is not allowed here">; def err_omp_typecheck_section_value : Error< diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index 2245fd78bfc9..8b4206e52cd4 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -114,6 +114,12 @@ class FileManager : public RefCountedBase { /// unsigned NextFileUID; + /// Statistics gathered during the lifetime of the FileManager. + unsigned NumDirLookups = 0; + unsigned NumFileLookups = 0; + unsigned NumDirCacheMisses = 0; + unsigned NumFileCacheMisses = 0; + // Caching. std::unique_ptr StatCache; @@ -341,6 +347,10 @@ private: public: void PrintStats() const; + + /// Import statistics from a child FileManager and add them to this current + /// FileManager. + void AddStats(const FileManager &Other); }; } // end namespace clang diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 75562284ec7d..e2a2aa71b880 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -57,6 +57,13 @@ enum class ShaderStage { Invalid, }; +enum class PointerAuthenticationMode : unsigned { + None, + Strip, + SignAndStrip, + SignAndAuth +}; + /// Bitfields of LangOptions, split out from LangOptions in order to ensure that /// this large collection of bitfields is a trivial class type. class LangOptionsBase { @@ -878,6 +885,8 @@ public: /// Return difference with the given option set. FPOptionsOverride getChangesFrom(const FPOptions &Base) const; + void applyChanges(FPOptionsOverride FPO); + // We can define most of the accessors automatically: #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ TYPE get##NAME() const { \ @@ -959,6 +968,11 @@ public: setAllowFPContractAcrossStatement(); } + void setDisallowOptimizations() { + setFPPreciseEnabled(true); + setDisallowFPContract(); + } + storage_type getAsOpaqueInt() const { return (static_cast(Options.getAsOpaqueInt()) << FPOptions::StorageBitSize) | @@ -1015,6 +1029,10 @@ inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const return getChangesSlow(Base); } +inline void FPOptions::applyChanges(FPOptionsOverride FPO) { + *this = FPO.applyOverrides(*this); +} + /// Describes the kind of translation unit being processed. enum TranslationUnitKind { /// The translation unit is a complete translation unit. diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h new file mode 100644 index 000000000000..e5cdcc31ebfb --- /dev/null +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -0,0 +1,23 @@ +//===--- PointerAuthOptions.h -----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines options for configuring pointer-auth technologies +// like ARMv8.3. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H + +namespace clang { + +constexpr unsigned PointerAuthKeyNone = -1; + +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index b4e3ae573b95..305f19daa4a9 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -71,7 +71,7 @@ def OffsetOfExpr : StmtNode; def UnaryExprOrTypeTraitExpr : StmtNode; def ArraySubscriptExpr : StmtNode; def MatrixSubscriptExpr : StmtNode; -def OMPArraySectionExpr : StmtNode; +def ArraySectionExpr : StmtNode; def OMPIteratorExpr : StmtNode; def CallExpr : StmtNode; def MemberExpr : StmtNode; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index e1ef7454f016..3ced2e7397a7 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -40,6 +40,7 @@ #include #include #include +#include #include namespace llvm { @@ -1792,6 +1793,15 @@ public: /// Whether to support HIP image/texture API's. virtual bool hasHIPImageSupport() const { return true; } + /// The first value in the pair is the minimum offset between two objects to + /// avoid false sharing (destructive interference). The second value in the + /// pair is maximum size of contiguous memory to promote true sharing + /// (constructive interference). Neither of these values are considered part + /// of the ABI and can be changed by targets at any time. + virtual std::pair hardwareInterferenceSizes() const { + return std::make_pair(64, 64); + } + protected: /// Copy type and layout related info. void copyAuxTarget(const TargetInfo *Aux); diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index 6d655c39360d..6390ba3f9fe5 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -275,7 +275,7 @@ def OP_VCVT_BF16_F32_HI_A32 (call "vget_low", $p0))>; def OP_CVT_F32_BF16 - : Op<(bitcast "R", (op "<<", (bitcast "int32_t", $p0), + : Op<(bitcast "R", (op "<<", (cast "int32_t", (bitcast "int16_t", $p0)), (literal "int32_t", "16")))>; //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index 6cc249837d3f..15340ebb62b3 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -1961,19 +1961,20 @@ def SVPSEL_D : SInst<"svpsel_lane_b64", "PPPm", "Pl", MergeNone, "", [IsStreamin // Standalone sve2.1 builtins let TargetGuard = "sve2p1" in { -def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>; -def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>; -def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfdcsilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>; -def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>; -def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>; -def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>; -def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>; -def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>; - -def SVFMAXNMQV: SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>; -def SVFMINNMQV: SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>; -def SVFMAXQV: SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>; -def SVFMINQV: SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>; +def SVORQV : SInst<"svorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orqv", [IsReductionQV]>; +def SVEORQV : SInst<"sveorqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorqv", [IsReductionQV]>; +def SVADDQV : SInst<"svaddqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_addqv", [IsReductionQV]>; +def SVANDQV : SInst<"svandqv[_{d}]", "{Pd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andqv", [IsReductionQV]>; +def SVSMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_smaxqv", [IsReductionQV]>; +def SVUMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxqv", [IsReductionQV]>; +def SVSMINQV : SInst<"svminqv[_{d}]", "{Pd", "csil", MergeNone, "aarch64_sve_sminqv", [IsReductionQV]>; +def SVUMINQV : SInst<"svminqv[_{d}]", "{Pd", "UcUsUiUl", MergeNone, "aarch64_sve_uminqv", [IsReductionQV]>; + +def SVFADDQV : SInst<"svaddqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_faddqv", [IsReductionQV]>; +def SVFMAXNMQV : SInst<"svmaxnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxnmqv", [IsReductionQV]>; +def SVFMINNMQV : SInst<"svminnmqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminnmqv", [IsReductionQV]>; +def SVFMAXQV : SInst<"svmaxqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fmaxqv", [IsReductionQV]>; +def SVFMINQV : SInst<"svminqv[_{d}]", "{Pd", "hfd", MergeNone, "aarch64_sve_fminqv", [IsReductionQV]>; } let TargetGuard = "sve2p1|sme2" in { diff --git a/clang/include/clang/Basic/riscv_vector.td b/clang/include/clang/Basic/riscv_vector.td index 76ed544f3b2b..cca4367751b9 100644 --- a/clang/include/clang/Basic/riscv_vector.td +++ b/clang/include/clang/Basic/riscv_vector.td @@ -14,14 +14,14 @@ include "riscv_vector_common.td" -defvar TypeList = ["c","s","i","l","x","f","d"]; +defvar TypeList = ["c","s","i","l","x","f","d","y"]; defvar EEWList = [["8", "(Log2EEW:3)"], ["16", "(Log2EEW:4)"], ["32", "(Log2EEW:5)"], ["64", "(Log2EEW:6)"]]; class IsFloat { - bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d")); + bit val = !or(!eq(type, "x"), !eq(type, "f"), !eq(type, "d"), !eq(type, "y")); } let SupportOverloading = false, @@ -118,7 +118,8 @@ multiclass RVVIndexedLoad { defvar eew_type = eew_list[1]; let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask", RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []) in { + !if(!eq(type, "y"), ["Zvfbfmin"], + [])) in { def: RVVOutOp1Builtin<"v", "vPCe" # eew_type # "Uv", type>; if !not(IsFloat.val) then { def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew_type # "Uv", type>; @@ -129,7 +130,8 @@ multiclass RVVIndexedLoad { defvar eew64_type = "(Log2EEW:6)"; let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask", RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"], - ["RV64"]) in { + !if(!eq(type, "y"), ["Zvfbfmin", "RV64"], + ["RV64"])) in { def: RVVOutOp1Builtin<"v", "vPCe" # eew64_type # "Uv", type>; if !not(IsFloat.val) then { def: RVVOutOp1Builtin<"Uv", "UvPCUe" # eew64_type # "Uv", type>; @@ -223,7 +225,8 @@ multiclass RVVIndexedStore { defvar eew_type = eew_list[1]; let Name = op # eew # "_v", IRName = op, MaskedIRName = op # "_mask", RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []) in { + !if(!eq(type, "y"), ["Zvfbfmin"], + [])) in { def : RVVBuiltin<"v", "0Pe" # eew_type # "Uvv", type>; if !not(IsFloat.val) then { def : RVVBuiltin<"Uv", "0PUe" # eew_type # "UvUv", type>; @@ -234,7 +237,8 @@ multiclass RVVIndexedStore { defvar eew64_type = "(Log2EEW:6)"; let Name = op # eew64 # "_v", IRName = op, MaskedIRName = op # "_mask", RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin", "RV64"], - ["RV64"]) in { + !if(!eq(type, "y"), ["Zvfbfmin", "RV64"], + ["RV64"])) in { def : RVVBuiltin<"v", "0Pe" # eew64_type # "Uvv", type>; if !not(IsFloat.val) then { def : RVVBuiltin<"Uv", "0PUe" # eew64_type # "UvUv", type>; @@ -358,6 +362,10 @@ multiclass RVVNonTupleVCreateBuiltin src_lmul_list> { def vcreate # src_v # dst_v : RVVBuiltin; + let RequiredFeatures = ["Zvfbfmin"] in + def vcreate_bf16 # src_v # dst_v : RVVBuiltin; defvar src_uv = FixedVString.V; defvar src_us = FixedVString.S; @@ -683,6 +691,8 @@ defm vle8: RVVVLEBuiltin<["c"]>; defm vle16: RVVVLEBuiltin<["s"]>; let Name = "vle16_v", RequiredFeatures = ["Zvfhmin"] in defm vle16_h: RVVVLEBuiltin<["x"]>; +let Name = "vle16_v", RequiredFeatures = ["Zvfbfmin"] in + defm vle16_bf16 : RVVVLEBuiltin<["y"]>; defm vle32: RVVVLEBuiltin<["i","f"]>; defm vle64: RVVVLEBuiltin<["l","d"]>; @@ -691,6 +701,8 @@ defm vse8 : RVVVSEBuiltin<["c"]>; defm vse16: RVVVSEBuiltin<["s"]>; let Name = "vse16_v", RequiredFeatures = ["Zvfhmin"] in defm vse16_h: RVVVSEBuiltin<["x"]>; +let Name = "vse16_v", RequiredFeatures = ["Zvfbfmin"] in + defm vse16_bf16: RVVVSEBuiltin<["y"]>; defm vse32: RVVVSEBuiltin<["i","f"]>; defm vse64: RVVVSEBuiltin<["l","d"]>; @@ -699,6 +711,8 @@ defm vlse8: RVVVLSEBuiltin<["c"]>; defm vlse16: RVVVLSEBuiltin<["s"]>; let Name = "vlse16_v", RequiredFeatures = ["Zvfhmin"] in defm vlse16_h: RVVVLSEBuiltin<["x"]>; +let Name = "vlse16_v", RequiredFeatures = ["Zvfbfmin"] in + defm vlse16_bf16: RVVVLSEBuiltin<["y"]>; defm vlse32: RVVVLSEBuiltin<["i","f"]>; defm vlse64: RVVVLSEBuiltin<["l","d"]>; @@ -706,6 +720,8 @@ defm vsse8 : RVVVSSEBuiltin<["c"]>; defm vsse16: RVVVSSEBuiltin<["s"]>; let Name = "vsse16_v", RequiredFeatures = ["Zvfhmin"] in defm vsse16_h: RVVVSSEBuiltin<["x"]>; +let Name = "vsse16_v", RequiredFeatures = ["Zvfbfmin"] in + defm vsse16_bf: RVVVSSEBuiltin<["y"]>; defm vsse32: RVVVSSEBuiltin<["i","f"]>; defm vsse64: RVVVSSEBuiltin<["l","d"]>; @@ -721,6 +737,8 @@ defm vle8ff: RVVVLEFFBuiltin<["c"]>; defm vle16ff: RVVVLEFFBuiltin<["s"]>; let Name = "vle16ff_v", RequiredFeatures = ["Zvfhmin"] in defm vle16ff: RVVVLEFFBuiltin<["x"]>; +let Name = "vle16ff_v", RequiredFeatures = ["Zvfbfmin"] in + defm vle16ff: RVVVLEFFBuiltin<["y"]>; defm vle32ff: RVVVLEFFBuiltin<["i", "f"]>; defm vle64ff: RVVVLEFFBuiltin<["l", "d"]>; @@ -732,14 +750,16 @@ multiclass RVVUnitStridedSegLoadTuple { !eq(type, "l") : "64", !eq(type, "x") : "16", !eq(type, "f") : "32", - !eq(type, "d") : "64"); + !eq(type, "d") : "64", + !eq(type, "y") : "16"); foreach nf = NFList in { let Name = op # nf # "e" # eew # "_v", IRName = op # nf, MaskedIRName = op # nf # "_mask", NF = nf, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { llvm::Type *ElementVectorType = cast(ResultType)->elements()[0]; @@ -793,7 +813,8 @@ multiclass RVVUnitStridedSegStoreTuple { !eq(type, "l") : "64", !eq(type, "x") : "16", !eq(type, "f") : "32", - !eq(type, "d") : "64"); + !eq(type, "d") : "64", + !eq(type, "y") : "16"); foreach nf = NFList in { let Name = op # nf # "e" # eew # "_v", IRName = op # nf, @@ -801,7 +822,8 @@ multiclass RVVUnitStridedSegStoreTuple { NF = nf, HasMaskedOffOperand = false, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { // Masked @@ -846,14 +868,16 @@ multiclass RVVUnitStridedSegLoadFFTuple { !eq(type, "l") : "64", !eq(type, "x") : "16", !eq(type, "f") : "32", - !eq(type, "d") : "64"); + !eq(type, "d") : "64", + !eq(type, "y") : "16"); foreach nf = NFList in { let Name = op # nf # "e" # eew # "ff_v", IRName = op # nf # "ff", MaskedIRName = op # nf # "ff_mask", NF = nf, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { llvm::Type *ElementVectorType = cast(ResultType)->elements()[0]; @@ -921,14 +945,16 @@ multiclass RVVStridedSegLoadTuple { !eq(type, "l") : "64", !eq(type, "x") : "16", !eq(type, "f") : "32", - !eq(type, "d") : "64"); + !eq(type, "d") : "64", + !eq(type, "y") : "16"); foreach nf = NFList in { let Name = op # nf # "e" # eew # "_v", IRName = op # nf, MaskedIRName = op # nf # "_mask", NF = nf, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { llvm::Type *ElementVectorType = cast(ResultType)->elements()[0]; @@ -983,7 +1009,8 @@ multiclass RVVStridedSegStoreTuple { !eq(type, "l") : "64", !eq(type, "x") : "16", !eq(type, "f") : "32", - !eq(type, "d") : "64"); + !eq(type, "d") : "64", + !eq(type, "y") : "16"); foreach nf = NFList in { let Name = op # nf # "e" # eew # "_v", IRName = op # nf, @@ -992,7 +1019,8 @@ multiclass RVVStridedSegStoreTuple { HasMaskedOffOperand = false, MaskedPolicyScheme = NonePolicy, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { // Masked @@ -1041,7 +1069,8 @@ multiclass RVVIndexedSegLoadTuple { MaskedIRName = op # nf # "_mask", NF = nf, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { llvm::Type *ElementVectorType = cast(ResultType)->elements()[0]; @@ -1104,7 +1133,8 @@ multiclass RVVIndexedSegStoreTuple { HasMaskedOffOperand = false, MaskedPolicyScheme = NonePolicy, RequiredFeatures = !if(!eq(type, "x"), ["Zvfhmin"], - []), + !if(!eq(type, "y"), ["Zvfbfmin"], + [])), ManualCodegen = [{ { // Masked @@ -2308,6 +2338,12 @@ let HasMasked = false, HasVL = false, IRName = "" in { def vreinterpret_h_i : RVVBuiltin<"vFv", "Fvv", "s", "Fv">; def vreinterpret_h_u : RVVBuiltin<"UvFv", "FvUv", "s", "Fv">; } + let RequiredFeatures = ["Zvfbfmin"] in { + def vreinterpret_i_bf16 : RVVBuiltin<"vIv", "Ivv", "y", "Iv">; + def vreinterpret_u_bf16 : RVVBuiltin<"vUv", "Uvv", "y", "Uv">; + def vreinterpret_bf16_i : RVVBuiltin<"Ivv", "vIv", "y", "v">; + def vreinterpret_bf16_u : RVVBuiltin<"Uvv", "vUv", "y", "v">; + } // Reinterpret between different SEW under the same LMUL foreach dst_sew = ["(FixedSEW:8)", "(FixedSEW:16)", "(FixedSEW:32)", @@ -2372,12 +2408,16 @@ let HasMasked = false, HasVL = false, IRName = "" in { return llvm::PoisonValue::get(ResultType); }] in { def vundefined : RVVBuiltin<"v", "v", "csilxfd">; + let RequiredFeatures = ["Zvfbfmin"] in + def vundefined_bf16 : RVVBuiltin<"v", "v", "y">; def vundefined_u : RVVBuiltin<"Uv", "Uv", "csil">; foreach nf = NFList in { let NF = nf in { defvar T = "(Tuple:" # nf # ")"; def : RVVBuiltin; + let RequiredFeatures = ["Zvfbfmin"] in + def : RVVBuiltin; def : RVVBuiltin; } } @@ -2396,6 +2436,9 @@ let HasMasked = false, HasVL = false, IRName = "" in { "(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in { def vlmul_trunc # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vv", "csilxfd", dst_lmul # "v">; + let RequiredFeatures = ["Zvfbfmin"] in + def vlmul_trunc_bf16 # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", + dst_lmul # "vv", "y", dst_lmul # "v">; def vlmul_trunc_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUv", "csil", dst_lmul # "Uv">; } @@ -2414,6 +2457,9 @@ let HasMasked = false, HasVL = false, IRName = "" in { "(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { def vlmul_ext # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vv", "csilxfd", dst_lmul # "v">; + let RequiredFeatures = ["Zvfbfmin"] in + def vlmul_ext_bf16 # dst_lmul : RVVBuiltin<"v" # dst_lmul # "v", + dst_lmul # "vv", "y", dst_lmul # "v">; def vlmul_ext_u # dst_lmul : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUv", "csil", dst_lmul # "Uv">; } @@ -2441,12 +2487,12 @@ let HasMasked = false, HasVL = false, IRName = "" in { } }] in { foreach dst_lmul = ["(SFixedLog2LMUL:0)", "(SFixedLog2LMUL:1)", "(SFixedLog2LMUL:2)"] in { - def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfd", dst_lmul # "v">; + def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "vvKz", "csilxfdy", dst_lmul # "v">; def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "UvUvKz", "csil", dst_lmul # "Uv">; } foreach nf = NFList in { defvar T = "(Tuple:" # nf # ")"; - def : RVVBuiltin; + def : RVVBuiltin; def : RVVBuiltin; } } @@ -2474,11 +2520,15 @@ let HasMasked = false, HasVL = false, IRName = "" in { }] in { foreach dst_lmul = ["(LFixedLog2LMUL:1)", "(LFixedLog2LMUL:2)", "(LFixedLog2LMUL:3)"] in { def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "csilxfd">; + let RequiredFeatures = ["Zvfbfmin"] in + def : RVVBuiltin<"v" # dst_lmul # "v", dst_lmul # "v" # dst_lmul # "vKzv", "y">; def : RVVBuiltin<"Uv" # dst_lmul # "Uv", dst_lmul # "Uv" # dst_lmul #"UvKzUv", "csil">; } foreach nf = NFList in { defvar T = "(Tuple:" # nf # ")"; def : RVVBuiltin<"v" # T # "v", T # "v" # T # "vKzv", "csilxfd">; + let RequiredFeatures = ["Zvfbfmin"] in + def : RVVBuiltin<"v" # T # "v", T # "v" # T # "vKzv", "y">; def : RVVBuiltin<"Uv" # T # "Uv", T # "Uv" # T # "UvKzUv", "csil">; } } @@ -2523,7 +2573,9 @@ let HasMasked = false, HasVL = false, IRName = "" in { defvar T = "(Tuple:" # nf # ")"; defvar V = VString.S; defvar UV = VString.S; - def : RVVBuiltin; + def : RVVBuiltin; + let RequiredFeatures = ["Zvfbfmin"] in + def : RVVBuiltin; def : RVVBuiltin; } } @@ -2549,8 +2601,7 @@ multiclass RVVOutBuiltinSetZvk { if HasVS then { foreach vs2_lmul = ["(SEFixedLog2LMUL:-1)", "(SEFixedLog2LMUL:0)", - "(SEFixedLog2LMUL:1)", "(SEFixedLog2LMUL:2)", - "(SEFixedLog2LMUL:3)"] in { + "(SEFixedLog2LMUL:1)", "(SEFixedLog2LMUL:2)"] in { defvar name = NAME # !if(!eq(NAME, "vaesz"), "", "_vs"); let OverloadedName = name, IRName = NAME # "_vs", Name = NAME # "_vs", IntrinsicTypes = [-1, 1] in diff --git a/clang/include/clang/CIR/CMakeLists.txt b/clang/include/clang/CIR/CMakeLists.txt index e69de29bb2d1..f8d6f407a03d 100644 --- a/clang/include/clang/CIR/CMakeLists.txt +++ b/clang/include/clang/CIR/CMakeLists.txt @@ -0,0 +1,6 @@ +set(MLIR_INCLUDE_DIR ${LLVM_MAIN_SRC_DIR}/../mlir/include ) # --includedir +set(MLIR_TABLEGEN_OUTPUT_DIR ${CMAKE_BINARY_DIR}/tools/mlir/include) +include_directories(${MLIR_INCLUDE_DIR}) +include_directories(${MLIR_TABLEGEN_OUTPUT_DIR}) + +add_subdirectory(Dialect) diff --git a/clang/include/clang/CIR/Dialect/CMakeLists.txt b/clang/include/clang/CIR/Dialect/CMakeLists.txt new file mode 100644 index 000000000000..f33061b2d87c --- /dev/null +++ b/clang/include/clang/CIR/Dialect/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(IR) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.h b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h new file mode 100644 index 000000000000..d53e5d1663d6 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.h @@ -0,0 +1,16 @@ +//===- CIRDialect.h - CIR dialect -------------------------------*- 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 declares the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H +#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT_H diff --git a/clang/include/clang/CIR/Dialect/IR/CIRDialect.td b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td new file mode 100644 index 000000000000..69d6e9774942 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRDialect.td @@ -0,0 +1,44 @@ +//===- CIRDialect.td - CIR dialect -------------------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache 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 declares the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT +#define LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT + +include "mlir/IR/OpBase.td" + +def CIR_Dialect : Dialect { + let name = "cir"; + + // A short one-line summary of our dialect. + let summary = "A high-level dialect for analyzing and optimizing Clang " + "supported languages"; + + let cppNamespace = "::mlir::cir"; + + let useDefaultAttributePrinterParser = 0; + let useDefaultTypePrinterParser = 0; + + let extraClassDeclaration = [{ + void registerAttributes(); + void registerTypes(); + + Type parseType(DialectAsmParser &parser) const override; + void printType(Type type, DialectAsmPrinter &printer) const override; + + Attribute parseAttribute(DialectAsmParser &parser, + Type type) const override; + + void printAttribute(Attribute attr, DialectAsmPrinter &os) const override; + }]; +} + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIRDIALECT diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td new file mode 100644 index 000000000000..7311c8db783e --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -0,0 +1,19 @@ +//===-- CIROps.td - CIR dialect definition -----------------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache 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 +/// Definition of the CIR dialect +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CIR_DIALECT_IR_CIROPS +#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS + +include "clang/CIR/Dialect/IR/CIRDialect.td" + +#endif // LLVM_CLANG_CIR_DIALECT_IR_CIROPS diff --git a/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt new file mode 100644 index 000000000000..28ae30dab8df --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CMakeLists.txt @@ -0,0 +1,16 @@ +# This replicates part of the add_mlir_dialect cmake function from MLIR that +# cannot be used here. This happens because it expects to be run inside MLIR +# directory which is not the case for CIR (and also FIR, both have similar +# workarounds). + +# Equivalent to add_mlir_dialect(CIROps cir) +set(LLVM_TARGET_DEFINITIONS CIROps.td) +mlir_tablegen(CIROps.h.inc -gen-op-decls) +mlir_tablegen(CIROps.cpp.inc -gen-op-defs) +mlir_tablegen(CIROpsTypes.h.inc -gen-typedef-decls) +mlir_tablegen(CIROpsTypes.cpp.inc -gen-typedef-defs) +mlir_tablegen(CIROpsDialect.h.inc -gen-dialect-decls) +mlir_tablegen(CIROpsDialect.cpp.inc -gen-dialect-defs) +add_public_tablegen_target(MLIRCIROpsIncGen) +add_dependencies(mlir-headers MLIRCIROpsIncGen) + diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 3c55aceecdde..263d1edf141a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2615,6 +2615,11 @@ defm protect_parens : BoolFOption<"protect-parens", "floating-point expressions are evaluated">, NegFlag>; +defm daz_ftz : SimpleMFlag<"daz-ftz", + "Globally set", "Do not globally set", + " the denormals-are-zero (DAZ) and flush-to-zero (FTZ) bits in the " + "floating-point control register on program startup">; + def ffor_scope : Flag<["-"], "ffor-scope">, Group; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group; @@ -4876,6 +4881,8 @@ def msimd128 : Flag<["-"], "msimd128">, Group; def mno_simd128 : Flag<["-"], "mno-simd128">, Group; def mrelaxed_simd : Flag<["-"], "mrelaxed-simd">, Group; def mno_relaxed_simd : Flag<["-"], "mno-relaxed-simd">, Group; +def mhalf_precision : Flag<["-"], "mhalf-precision">, Group; +def mno_half_precision : Flag<["-"], "mno-half-precision">, Group; def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group; def mno_nontrapping_fptoint : Flag<["-"], "mno-nontrapping-fptoint">, Group; def msign_ext : Flag<["-"], "msign-ext">, Group; @@ -5508,6 +5515,14 @@ def fno_rtlib_add_rpath: Flag<["-"], "fno-rtlib-add-rpath">, Visibility<[ClangOption, FlangOption]>, HelpText<"Do not add -rpath with architecture-specific resource directory to the linker flags. " "When --hip-link is specified, do not add -rpath with HIP runtime library directory to the linker flags">; +def frtlib_defaultlib : Flag<["-"], "frtlib-defaultlib">, + Visibility<[ClangOption, CLOption]>, + Group, + HelpText<"On Windows, emit /defaultlib: directives to link compiler-rt libraries (default)">; +def fno_rtlib_defaultlib : Flag<["-"], "fno-rtlib-defaultlib">, + Visibility<[ClangOption, CLOption]>, + Group, + HelpText<"On Windows, do not emit /defaultlib: directives to link compiler-rt libraries">; def offload_add_rpath: Flag<["--"], "offload-add-rpath">, Flags<[NoArgumentUnused]>, Alias; @@ -6574,12 +6589,6 @@ def J : JoinedOrSeparate<["-"], "J">, Group, Alias; -let Visibility = [FlangOption] in { -def no_fortran_main : Flag<["-"], "fno-fortran-main">, - Visibility<[FlangOption]>, Group, - HelpText<"Do not include Fortran_main.a (provided by Flang) when linking">; -} // let Visibility = [ FlangOption ] - //===----------------------------------------------------------------------===// // FC1 Options //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/ExtractAPI/API.h b/clang/include/clang/ExtractAPI/API.h index 92cacf65c7d6..d323e1668a72 100644 --- a/clang/include/clang/ExtractAPI/API.h +++ b/clang/include/clang/ExtractAPI/API.h @@ -208,20 +208,20 @@ struct APIRecord { RK_ClassTemplate, RK_ClassTemplateSpecialization, RK_ClassTemplatePartialSpecialization, - RK_LastRecordContext, - RK_GlobalFunction, - RK_GlobalFunctionTemplate, - RK_GlobalFunctionTemplateSpecialization, + RK_StructField, + RK_UnionField, + RK_CXXField, + RK_StaticField, + RK_CXXFieldTemplate, RK_GlobalVariable, RK_GlobalVariableTemplate, RK_GlobalVariableTemplateSpecialization, RK_GlobalVariableTemplatePartialSpecialization, + RK_LastRecordContext, + RK_GlobalFunction, + RK_GlobalFunctionTemplate, + RK_GlobalFunctionTemplateSpecialization, RK_EnumConstant, - RK_StructField, - RK_UnionField, - RK_StaticField, - RK_CXXField, - RK_CXXFieldTemplate, RK_Concept, RK_CXXStaticMethod, RK_CXXInstanceMethod, @@ -321,6 +321,10 @@ public: RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {} + /// Append \p Other children chain into ours and empty out Other's record + /// chain. + void stealRecordChain(RecordContext &Other); + APIRecord::RecordKind getKind() const { return Kind; } struct record_iterator { @@ -370,6 +374,7 @@ private: APIRecord::RecordKind Kind; mutable APIRecord *First = nullptr; mutable APIRecord *Last = nullptr; + bool IsWellFormed() const; protected: friend class APISet; @@ -475,7 +480,7 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord { }; /// This holds information associated with global functions. -struct GlobalVariableRecord : APIRecord { +struct GlobalVariableRecord : APIRecord, RecordContext { GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, LinkageInfo Linkage, const DocComment &Comment, @@ -483,23 +488,28 @@ struct GlobalVariableRecord : APIRecord { DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, - SubHeading, IsFromSystemHeader) {} + SubHeading, IsFromSystemHeader), + RecordContext(RK_GlobalVariable) {} GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name, - SymbolReference Parent, - - PresumedLoc Loc, AvailabilityInfo Availability, - LinkageInfo Linkage, const DocComment &Comment, + SymbolReference Parent, PresumedLoc Loc, + AvailabilityInfo Availability, LinkageInfo Linkage, + const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading, - IsFromSystemHeader) {} + IsFromSystemHeader), + RecordContext(Kind) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); } - static bool classofKind(RecordKind K) { return K == RK_GlobalVariable; } + static bool classofKind(RecordKind K) { + return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate || + K == RK_GlobalVariableTemplateSpecialization || + K == RK_GlobalVariableTemplatePartialSpecialization; + } private: virtual void anchor(); @@ -591,20 +601,47 @@ private: virtual void anchor(); }; +struct TagRecord : APIRecord, RecordContext { + TagRecord(RecordKind Kind, StringRef USR, StringRef Name, + SymbolReference Parent, PresumedLoc Loc, + AvailabilityInfo Availability, const DocComment &Comment, + DeclarationFragments Declaration, DeclarationFragments SubHeading, + bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator, + AccessControl Access = AccessControl()) + : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), + LinkageInfo::none(), Comment, Declaration, SubHeading, + IsFromSystemHeader, std::move(Access)), + RecordContext(Kind), + IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){}; + + static bool classof(const APIRecord *Record) { + return classofKind(Record->getKind()); + } + static bool classofKind(RecordKind K) { + return K == RK_Struct || K == RK_Union || K == RK_Enum; + } + + bool IsEmbeddedInVarDeclarator; + + virtual ~TagRecord() = 0; +}; + /// This holds information associated with enums. -struct EnumRecord : APIRecord, RecordContext { +struct EnumRecord : TagRecord { EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability), - LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader), - RecordContext(RK_Enum) {} + DeclarationFragments SubHeading, bool IsFromSystemHeader, + bool IsEmbeddedInVarDeclarator, + AccessControl Access = AccessControl()) + : TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability), + Comment, Declaration, SubHeading, IsFromSystemHeader, + IsEmbeddedInVarDeclarator, std::move(Access)) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); } + static bool classofKind(RecordKind K) { return K == RK_Enum; } private: @@ -612,7 +649,7 @@ private: }; /// This holds information associated with struct or union fields fields. -struct RecordFieldRecord : APIRecord { +struct RecordFieldRecord : APIRecord, RecordContext { RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, @@ -620,7 +657,8 @@ struct RecordFieldRecord : APIRecord { DeclarationFragments SubHeading, bool IsFromSystemHeader) : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader) {} + IsFromSystemHeader), + RecordContext(Kind) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); @@ -633,16 +671,17 @@ struct RecordFieldRecord : APIRecord { }; /// This holds information associated with structs and unions. -struct RecordRecord : APIRecord, RecordContext { +struct RecordRecord : TagRecord { RecordRecord(RecordKind Kind, StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) - : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), - LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader), - RecordContext(Kind) {} + DeclarationFragments SubHeading, bool IsFromSystemHeader, + bool IsEmbeddedInVarDeclarator, + AccessControl Access = AccessControl()) + : TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), + Comment, Declaration, SubHeading, IsFromSystemHeader, + IsEmbeddedInVarDeclarator, std::move(Access)) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); @@ -651,6 +690,8 @@ struct RecordRecord : APIRecord, RecordContext { return K == RK_Struct || K == RK_Union; } + bool isAnonymousWithNoTypedef() { return Name.empty(); } + virtual ~RecordRecord() = 0; }; @@ -676,9 +717,11 @@ struct StructRecord : RecordRecord { StructRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) + DeclarationFragments SubHeading, bool IsFromSystemHeader, + bool IsEmbeddedInVarDeclarator) : RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability), - Comment, Declaration, SubHeading, IsFromSystemHeader) {} + Comment, Declaration, SubHeading, IsFromSystemHeader, + IsEmbeddedInVarDeclarator) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); @@ -711,9 +754,11 @@ struct UnionRecord : RecordRecord { UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, - DeclarationFragments SubHeading, bool IsFromSystemHeader) + DeclarationFragments SubHeading, bool IsFromSystemHeader, + bool IsEmbeddedInVarDeclarator) : RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability), - Comment, Declaration, SubHeading, IsFromSystemHeader) {} + Comment, Declaration, SubHeading, IsFromSystemHeader, + IsEmbeddedInVarDeclarator) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); @@ -724,7 +769,7 @@ private: virtual void anchor(); }; -struct CXXFieldRecord : APIRecord { +struct CXXFieldRecord : APIRecord, RecordContext { CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, @@ -732,7 +777,8 @@ struct CXXFieldRecord : APIRecord { bool IsFromSystemHeader) : APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability), LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader, std::move(Access)) {} + IsFromSystemHeader, std::move(Access)), + RecordContext(RK_CXXField) {} CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, @@ -742,7 +788,8 @@ struct CXXFieldRecord : APIRecord { bool IsFromSystemHeader) : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader, std::move(Access)) {} + IsFromSystemHeader, std::move(Access)), + RecordContext(Kind) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); @@ -1118,18 +1165,18 @@ struct ObjCContainerRecord : APIRecord, RecordContext { virtual ~ObjCContainerRecord() = 0; }; -struct CXXClassRecord : APIRecord, RecordContext { +struct CXXClassRecord : RecordRecord { SmallVector Bases; CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent, PresumedLoc Loc, AvailabilityInfo Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, RecordKind Kind, - AccessControl Access, bool IsFromSystemHeader) - : APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), - LinkageInfo::none(), Comment, Declaration, SubHeading, - IsFromSystemHeader, std::move(Access)), - RecordContext(Kind) {} + AccessControl Access, bool IsFromSystemHeader, + bool IsEmbeddedInVarDeclarator = false) + : RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability), + Comment, Declaration, SubHeading, IsFromSystemHeader, + IsEmbeddedInVarDeclarator, std::move(Access)) {} static bool classof(const APIRecord *Record) { return classofKind(Record->getKind()); diff --git a/clang/include/clang/ExtractAPI/APIRecords.inc b/clang/include/clang/ExtractAPI/APIRecords.inc index 15fee809656d..4cda4ef2f9be 100644 --- a/clang/include/clang/ExtractAPI/APIRecords.inc +++ b/clang/include/clang/ExtractAPI/APIRecords.inc @@ -35,10 +35,11 @@ CONCRETE_RECORD(GlobalVariableTemplateSpecializationRecord, CONCRETE_RECORD(GlobalVariableTemplatePartialSpecializationRecord, GlobalVariableRecord, RK_GlobalVariableTemplatePartialSpecialization) +ABSTRACT_RECORD(TagRecord, APIRecord) CONCRETE_RECORD(EnumConstantRecord, APIRecord, RK_EnumConstant) -CONCRETE_RECORD(EnumRecord, APIRecord, RK_Enum) +CONCRETE_RECORD(EnumRecord, TagRecord, RK_Enum) ABSTRACT_RECORD(RecordFieldRecord, APIRecord) -ABSTRACT_RECORD(RecordRecord, APIRecord) +ABSTRACT_RECORD(RecordRecord, TagRecord) CONCRETE_RECORD(StructFieldRecord, RecordFieldRecord, RK_StructField) CONCRETE_RECORD(StructRecord, APIRecord, RK_Struct) CONCRETE_RECORD(UnionFieldRecord, RecordFieldRecord, RK_UnionField) @@ -99,5 +100,16 @@ RECORD_CONTEXT(ClassTemplateSpecializationRecord, RK_ClassTemplateSpecialization) RECORD_CONTEXT(ClassTemplatePartialSpecializationRecord, RK_ClassTemplatePartialSpecialization) +RECORD_CONTEXT(StructFieldRecord, RK_StructField) +RECORD_CONTEXT(UnionFieldRecord, RK_UnionField) +RECORD_CONTEXT(CXXFieldRecord, RK_CXXField) +RECORD_CONTEXT(StaticFieldRecord, RK_StaticField) +RECORD_CONTEXT(CXXFieldTemplateRecord, RK_CXXFieldTemplate) +RECORD_CONTEXT(GlobalVariableRecord, RK_GlobalVariable) +RECORD_CONTEXT(GlobalVariableTemplateRecord, RK_GlobalVariableTemplate) +RECORD_CONTEXT(GlobalVariableTemplateSpecializationRecord, + RK_GlobalVariableTemplateSpecialization) +RECORD_CONTEXT(GlobalVariableTemplatePartialSpecializationRecord, + RK_GlobalVariableTemplatePartialSpecialization) #undef RECORD_CONTEXT diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h index 94392c185165..535da90b9828 100644 --- a/clang/include/clang/ExtractAPI/DeclarationFragments.h +++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h @@ -27,6 +27,8 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/MacroInfo.h" +#include +#include #include namespace clang { @@ -113,28 +115,26 @@ public: ConstFragmentIterator cend() const { return Fragments.cend(); } - // Add a new Fragment at an arbitrary offset. - DeclarationFragments &insert(FragmentIterator It, StringRef Spelling, - FragmentKind Kind, - StringRef PreciseIdentifier = "", - const Decl *Declaration = nullptr) { - Fragments.insert(It, - Fragment(Spelling, Kind, PreciseIdentifier, Declaration)); - return *this; + /// Prepend another DeclarationFragments to the beginning. + /// + /// \returns a reference to the DeclarationFragments object itself after + /// appending to chain up consecutive operations. + DeclarationFragments &prepend(DeclarationFragments Other) { + return insert(begin(), std::move(Other)); } - DeclarationFragments &insert(FragmentIterator It, - DeclarationFragments &&Other) { - Fragments.insert(It, std::make_move_iterator(Other.Fragments.begin()), - std::make_move_iterator(Other.Fragments.end())); - Other.Fragments.clear(); - return *this; + /// Append another DeclarationFragments to the end. + /// + /// \returns a reference to the DeclarationFragments object itself after + /// appending to chain up consecutive operations. + DeclarationFragments &append(DeclarationFragments Other) { + return insert(end(), std::move(Other)); } /// Append a new Fragment to the end of the Fragments. /// /// \returns a reference to the DeclarationFragments object itself after - /// appending to chain up consecutive appends. + /// appending to chain up consecutive operations. DeclarationFragments &append(StringRef Spelling, FragmentKind Kind, StringRef PreciseIdentifier = "", const Decl *Declaration = nullptr) { @@ -149,18 +149,48 @@ public: return *this; } - /// Append another DeclarationFragments to the end. - /// - /// Note: \p Other is moved from and cannot be used after a call to this - /// method. + /// Inserts another DeclarationFragments at \p It. /// /// \returns a reference to the DeclarationFragments object itself after - /// appending to chain up consecutive appends. - DeclarationFragments &append(DeclarationFragments &&Other) { - Fragments.insert(Fragments.end(), - std::make_move_iterator(Other.Fragments.begin()), - std::make_move_iterator(Other.Fragments.end())); - Other.Fragments.clear(); + /// appending to chain up consecutive operations. + DeclarationFragments &insert(FragmentIterator It, + DeclarationFragments Other) { + if (Other.Fragments.empty()) + return *this; + + if (Fragments.empty()) { + Fragments = std::move(Other.Fragments); + return *this; + } + + const auto &OtherFrags = Other.Fragments; + auto ToInsertBegin = std::make_move_iterator(Other.begin()); + auto ToInsertEnd = std::make_move_iterator(Other.end()); + + // If we aren't inserting at the end let's make sure that we merge their + // last fragment with It if both are text fragments. + if (It != end() && It->Kind == FragmentKind::Text && + OtherFrags.back().Kind == FragmentKind::Text) { + auto &TheirBackSpelling = OtherFrags.back().Spelling; + It->Spelling.reserve(It->Spelling.size() + TheirBackSpelling.size()); + It->Spelling.insert(It->Spelling.begin(), TheirBackSpelling.begin(), + TheirBackSpelling.end()); + --ToInsertEnd; + } + + // If we aren't inserting at the beginning we want to merge their first + // fragment with the fragment before It if both are text fragments. + if (It != begin() && std::prev(It)->Kind == FragmentKind::Text && + OtherFrags.front().Kind == FragmentKind::Text) { + auto PrevIt = std::prev(It); + auto &TheirFrontSpelling = OtherFrags.front().Spelling; + PrevIt->Spelling.reserve(PrevIt->Spelling.size() + + TheirFrontSpelling.size()); + PrevIt->Spelling.append(TheirFrontSpelling); + ++ToInsertBegin; + } + + Fragments.insert(It, ToInsertBegin, ToInsertEnd); return *this; } @@ -177,13 +207,13 @@ public: /// Append a text Fragment of a space character. /// /// \returns a reference to the DeclarationFragments object itself after - /// appending to chain up consecutive appends. + /// appending to chain up consecutive operations. DeclarationFragments &appendSpace(); /// Append a text Fragment of a semicolon character. /// /// \returns a reference to the DeclarationFragments object itself after - /// appending to chain up consecutive appends. + /// appending to chain up consecutive operations. DeclarationFragments &appendSemicolon(); /// Removes a trailing semicolon character if present. diff --git a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h index 4cb866892b5d..97cc457ea2a9 100644 --- a/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h +++ b/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h @@ -224,6 +224,29 @@ protected: return API.createSymbolReference(Name, USR, getOwningModuleName(D)); } + + bool isEmbeddedInVarDeclarator(const TagDecl &D) { + return D.getName().empty() && getTypedefName(&D).empty() && + D.isEmbeddedInDeclarator(); + } + + void maybeMergeWithAnonymousTag(const DeclaratorDecl &D, + RecordContext *NewRecordContext) { + if (!NewRecordContext) + return; + auto *Tag = D.getType()->getAsTagDecl(); + SmallString<128> TagUSR; + clang::index::generateUSRForDecl(Tag, TagUSR); + if (auto *Record = llvm::dyn_cast_if_present( + API.findRecordForUSR(TagUSR))) { + if (Record->IsEmbeddedInVarDeclarator) { + NewRecordContext->stealRecordChain(*Record); + auto *NewRecord = cast(NewRecordContext); + if (NewRecord->Comment.empty()) + NewRecord->Comment = Record->Comment; + } + } + } }; template @@ -273,12 +296,18 @@ bool ExtractAPIVisitorBase::VisitVarDecl(const VarDecl *Decl) { USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, SubHeading, Access, isInSystemHeader(Decl)); - } else + } else { // Add the global variable record to the API set. - API.createRecord( + auto *NewRecord = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, SubHeading, isInSystemHeader(Decl)); + + // If this global variable has a non typedef'd anonymous tag type let's + // pretend the type's child records are under us in the hierarchy. + maybeMergeWithAnonymousTag(*Decl, NewRecord); + } + return true; } @@ -364,7 +393,7 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { if (Name.empty()) { llvm::raw_svector_ostream OS(QualifiedNameBuffer); Decl->printQualifiedName(OS); - Name = QualifiedNameBuffer.str(); + Name = QualifiedNameBuffer; } SmallString<128> USR; @@ -385,7 +414,7 @@ bool ExtractAPIVisitorBase::VisitEnumDecl(const EnumDecl *Decl) { auto *ER = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, - isInSystemHeader(Decl)); + isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); // Now collect information about the enumerators in this enum. getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators()); @@ -510,16 +539,10 @@ bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) return true; - SmallString<128> QualifiedNameBuffer; // Collect symbol information. StringRef Name = Decl->getName(); if (Name.empty()) Name = getTypedefName(Decl); - if (Name.empty()) { - llvm::raw_svector_ostream OS(QualifiedNameBuffer); - Decl->printQualifiedName(OS); - Name = QualifiedNameBuffer.str(); - } SmallString<128> USR; index::generateUSRForDecl(Decl, USR); @@ -541,12 +564,12 @@ bool ExtractAPIVisitorBase::VisitRecordDecl(const RecordDecl *Decl) { API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, - SubHeading, isInSystemHeader(Decl)); + SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); else API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, - SubHeading, isInSystemHeader(Decl)); + SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl)); return true; } @@ -559,6 +582,9 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( return true; StringRef Name = Decl->getName(); + if (Name.empty()) + Name = getTypedefName(Decl); + SmallString<128> USR; index::generateUSRForDecl(Decl, USR); PresumedLoc Loc = @@ -585,8 +611,7 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( CXXClassRecord *Record; if (Decl->getDescribedClassTemplate()) { // Inject template fragments before class fragments. - Declaration.insert( - Declaration.begin(), + Declaration.prepend( DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( Decl->getDescribedClassTemplate())); Record = API.createRecord( @@ -598,7 +623,8 @@ bool ExtractAPIVisitorBase::VisitCXXRecordDecl( Record = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, - SubHeading, Kind, Access, isInSystemHeader(Decl)); + SubHeading, Kind, Access, isInSystemHeader(Decl), + isEmbeddedInVarDeclarator(*Decl)); Record->Bases = getBases(Decl); @@ -1075,18 +1101,17 @@ bool ExtractAPIVisitorBase::VisitTypedefNameDecl( // If the underlying type was defined as part of the typedef modify it's // fragments directly and pretend the typedef doesn't exist. if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) { - if (TagDecl->getName() == Decl->getName() && - TagDecl->isEmbeddedInDeclarator() && TagDecl->isCompleteDefinition()) { + if (TagDecl->isEmbeddedInDeclarator() && TagDecl->isCompleteDefinition() && + Decl->getName() == TagDecl->getName()) { SmallString<128> TagUSR; index::generateUSRForDecl(TagDecl, TagUSR); if (auto *Record = API.findRecordForUSR(TagUSR)) { DeclarationFragments LeadingFragments; LeadingFragments.append("typedef", - DeclarationFragments::FragmentKind::Keyword, "", - nullptr); + DeclarationFragments::FragmentKind::Keyword); LeadingFragments.appendSpace(); Record->Declaration.removeTrailingSemicolon() - .insert(Record->Declaration.begin(), std::move(LeadingFragments)) + .prepend(std::move(LeadingFragments)) .append(" { ... } ", DeclarationFragments::FragmentKind::Text) .append(Name, DeclarationFragments::FragmentKind::Identifier) .appendSemicolon(); @@ -1221,26 +1246,31 @@ bool ExtractAPIVisitorBase::VisitFieldDecl(const FieldDecl *Decl) { DeclarationFragments SubHeading = DeclarationFragmentsBuilder::getSubHeading(Decl); + RecordContext *NewRecord = nullptr; if (isa(Decl->getDeclContext())) { AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); - API.createRecord( + NewRecord = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, Access, isInSystemHeader(Decl)); } else if (auto *RD = dyn_cast(Decl->getDeclContext())) { if (RD->isUnion()) - API.createRecord( + NewRecord = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, isInSystemHeader(Decl)); else - API.createRecord( + NewRecord = API.createRecord( USR, Name, createHierarchyInformationForDecl(*Decl), Loc, AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, isInSystemHeader(Decl)); } + // If this field has a non typedef'd anonymous tag type let's pretend the + // type's child records are under us in the hierarchy. + maybeMergeWithAnonymousTag(*Decl, NewRecord); + return true; } diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index a2c1b25dd224..080844893c13 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -241,7 +241,7 @@ private: /// A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. - std::vector TopLevelDeclsInPreamble; + std::vector TopLevelDeclsInPreamble; /// Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults : 1; diff --git a/clang/include/clang/Frontend/MultiplexConsumer.h b/clang/include/clang/Frontend/MultiplexConsumer.h index 7f8d2858b386..f29c8e92fded 100644 --- a/clang/include/clang/Frontend/MultiplexConsumer.h +++ b/clang/include/clang/Frontend/MultiplexConsumer.h @@ -35,7 +35,7 @@ public: void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; void MacroRead(serialization::MacroID ID, MacroInfo *MI) override; void TypeRead(serialization::TypeIdx Idx, QualType T) override; - void DeclRead(serialization::DeclID ID, const Decl *D) override; + void DeclRead(GlobalDeclID ID, const Decl *D) override; void SelectorRead(serialization::SelectorID iD, Selector Sel) override; void MacroDefinitionRead(serialization::PreprocessedEntityID, MacroDefinitionRecord *MD) override; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index c5f90ef4cb36..5ac63dddd4d4 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -56,6 +56,12 @@ class TargetInfo; /// The preprocessor keeps track of this information for each /// file that is \#included. struct HeaderFileInfo { + // TODO: Whether the file was included is not a property of the file itself. + // It's a preprocessor state, move it there. + /// True if this file has been included (or imported) **locally**. + LLVM_PREFERRED_TYPE(bool) + unsigned IsLocallyIncluded : 1; + // TODO: Whether the file was imported is not a property of the file itself. // It's a preprocessor state, move it there. /// True if this is a \#import'd file. @@ -135,10 +141,10 @@ struct HeaderFileInfo { StringRef Framework; HeaderFileInfo() - : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), - External(false), isModuleHeader(false), isTextualModuleHeader(false), - isCompilingModuleHeader(false), Resolved(false), - IndexHeaderMapHeader(false), IsValid(false) {} + : IsLocallyIncluded(false), isImport(false), isPragmaOnce(false), + DirInfo(SrcMgr::C_User), External(false), isModuleHeader(false), + isTextualModuleHeader(false), isCompilingModuleHeader(false), + Resolved(false), IndexHeaderMapHeader(false), IsValid(false) {} /// Retrieve the controlling macro for this header file, if /// any. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index d3bb04ff7a2c..fb117bf04087 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -313,7 +313,15 @@ class Parser : public CodeCompletionHandler { /// top-level declaration is finished. SmallVector TemplateIds; + /// Don't destroy template annotations in MaybeDestroyTemplateIds even if + /// we're at the end of a declaration. Instead, we defer the destruction until + /// after a top-level declaration. + /// Use DelayTemplateIdDestructionRAII rather than setting it directly. + bool DelayTemplateIdDestruction = false; + void MaybeDestroyTemplateIds() { + if (DelayTemplateIdDestruction) + return; if (!TemplateIds.empty() && (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens())) DestroyTemplateIds(); @@ -329,6 +337,22 @@ class Parser : public CodeCompletionHandler { ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); } }; + struct DelayTemplateIdDestructionRAII { + Parser &Self; + bool PrevDelayTemplateIdDestruction; + + DelayTemplateIdDestructionRAII(Parser &Self, + bool DelayTemplateIdDestruction) noexcept + : Self(Self), + PrevDelayTemplateIdDestruction(Self.DelayTemplateIdDestruction) { + Self.DelayTemplateIdDestruction = DelayTemplateIdDestruction; + } + + ~DelayTemplateIdDestructionRAII() noexcept { + Self.DelayTemplateIdDestruction = PrevDelayTemplateIdDestruction; + } + }; + /// Identifiers which have been declared within a tentative parse. SmallVector TentativelyDeclaredIdentifiers; @@ -2967,25 +2991,25 @@ private: Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None, const IdentifierInfo *EnclosingScope = nullptr); - void MaybeParseHLSLSemantics(Declarator &D, - SourceLocation *EndLoc = nullptr) { - assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only"); + void MaybeParseHLSLAnnotations(Declarator &D, + SourceLocation *EndLoc = nullptr) { + assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only"); if (Tok.is(tok::colon)) { ParsedAttributes Attrs(AttrFactory); - ParseHLSLSemantics(Attrs, EndLoc); + ParseHLSLAnnotations(Attrs, EndLoc); D.takeAttributes(Attrs); } } - void MaybeParseHLSLSemantics(ParsedAttributes &Attrs, - SourceLocation *EndLoc = nullptr) { - assert(getLangOpts().HLSL && "MaybeParseHLSLSemantics is for HLSL only"); + void MaybeParseHLSLAnnotations(ParsedAttributes &Attrs, + SourceLocation *EndLoc = nullptr) { + assert(getLangOpts().HLSL && "MaybeParseHLSLAnnotations is for HLSL only"); if (getLangOpts().HLSL && Tok.is(tok::colon)) - ParseHLSLSemantics(Attrs, EndLoc); + ParseHLSLAnnotations(Attrs, EndLoc); } - void ParseHLSLSemantics(ParsedAttributes &Attrs, - SourceLocation *EndLoc = nullptr); + void ParseHLSLAnnotations(ParsedAttributes &Attrs, + SourceLocation *EndLoc = nullptr); Decl *ParseHLSLBuffer(SourceLocation &DeclEnd); void MaybeParseMicrosoftAttributes(ParsedAttributes &Attrs) { diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index c9eecdafe62c..760c7980be52 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -36,6 +36,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include namespace clang { class ASTContext; @@ -1790,6 +1791,7 @@ public: struct Binding { IdentifierInfo *Name; SourceLocation NameLoc; + std::optional Attrs; }; private: @@ -2339,10 +2341,10 @@ public: } /// Set the decomposition bindings for this declarator. - void - setDecompositionBindings(SourceLocation LSquareLoc, - ArrayRef Bindings, - SourceLocation RSquareLoc); + void setDecompositionBindings( + SourceLocation LSquareLoc, + MutableArrayRef Bindings, + SourceLocation RSquareLoc); /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to /// EndLoc, which should be the last token of the chunk. diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 2bf91cb5212c..238fb398b7d1 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -65,7 +65,7 @@ public: /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetExternalDecl(uint32_t ID) override; + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Complete the redeclaration chain if it's been extended since the /// previous generation of the AST source. diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index 25a5fa05b21c..8368d9ce6146 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -948,6 +948,7 @@ public: ParsedAttributes(AttributeFactory &factory) : pool(factory) {} ParsedAttributes(const ParsedAttributes &) = delete; ParsedAttributes &operator=(const ParsedAttributes &) = delete; + ParsedAttributes(ParsedAttributes &&G) = default; AttributePool &getPool() const { return pool; } diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 64607b91acbf..1ca523ec88c2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3084,6 +3084,7 @@ public: Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, SkipBodyInfo *SkipBody = nullptr, FnBodyKind BodyKind = FnBodyKind::Other); + void applyFunctionAttributesBeforeParsingBody(Decl *FD); /// Determine whether we can delay parsing the body of a function or /// function template until it is used, assuming we don't care about emitting diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index ea28617f79b8..da19503c2902 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -193,6 +193,12 @@ public: /// conversions and diagnostics to 'int'. ExprResult ActOnIntExpr(OpenACCDirectiveKind DK, OpenACCClauseKind CK, SourceLocation Loc, Expr *IntExpr); + + /// Checks and creates an Array Section used in an OpenACC construct/clause. + ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, + Expr *LowerBound, + SourceLocation ColonLocFirst, Expr *Length, + SourceLocation RBLoc); }; } // namespace clang diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 500098dd3dab..a8df5a0bda08 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H #define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H +#include "clang/AST/DeclID.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "clang/Basic/IdentifierTable.h" @@ -59,18 +60,9 @@ const unsigned VERSION_MINOR = 1; /// and start at 1. 0 is reserved for NULL. using IdentifierID = uint32_t; -/// An ID number that refers to a declaration in an AST file. -/// -/// The ID numbers of declarations are consecutive (in order of -/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. -/// At the start of a chain of precompiled headers, declaration ID 1 is -/// used for the translation unit declaration. -using DeclID = uint32_t; - -// FIXME: Turn these into classes so we can have some type safety when -// we go from local ID to global and vice-versa. -using LocalDeclID = DeclID; -using GlobalDeclID = DeclID; +/// An ID number that refers to a declaration in an AST file. See the comments +/// in DeclIDBase for details. +using DeclID = DeclIDBase::DeclID; /// An ID number that refers to a type in an AST file. /// @@ -981,8 +973,8 @@ enum PredefinedTypeIDs { /// OpenCL reserve_id type. PREDEF_TYPE_RESERVE_ID_ID = 41, - /// The placeholder type for OpenMP array section. - PREDEF_TYPE_OMP_ARRAY_SECTION = 42, + /// The placeholder type for an array section. + PREDEF_TYPE_ARRAY_SECTION = 42, /// The '__float128' type PREDEF_TYPE_FLOAT128_ID = 43, @@ -1165,74 +1157,6 @@ enum SpecialTypeIDs { /// The number of special type IDs. const unsigned NumSpecialTypeIDs = 8; -/// Predefined declaration IDs. -/// -/// These declaration IDs correspond to predefined declarations in the AST -/// context, such as the NULL declaration ID. Such declarations are never -/// actually serialized, since they will be built by the AST context when -/// it is created. -enum PredefinedDeclIDs { - /// The NULL declaration. - PREDEF_DECL_NULL_ID = 0, - - /// The translation unit. - PREDEF_DECL_TRANSLATION_UNIT_ID = 1, - - /// The Objective-C 'id' type. - PREDEF_DECL_OBJC_ID_ID = 2, - - /// The Objective-C 'SEL' type. - PREDEF_DECL_OBJC_SEL_ID = 3, - - /// The Objective-C 'Class' type. - PREDEF_DECL_OBJC_CLASS_ID = 4, - - /// The Objective-C 'Protocol' type. - PREDEF_DECL_OBJC_PROTOCOL_ID = 5, - - /// The signed 128-bit integer type. - PREDEF_DECL_INT_128_ID = 6, - - /// The unsigned 128-bit integer type. - PREDEF_DECL_UNSIGNED_INT_128_ID = 7, - - /// The internal 'instancetype' typedef. - PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, - - /// The internal '__builtin_va_list' typedef. - PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, - - /// The internal '__va_list_tag' struct, if any. - PREDEF_DECL_VA_LIST_TAG = 10, - - /// The internal '__builtin_ms_va_list' typedef. - PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, - - /// The predeclared '_GUID' struct. - PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, - - /// The extern "C" context. - PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, - - /// The internal '__make_integer_seq' template. - PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, - - /// The internal '__NSConstantString' typedef. - PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, - - /// The internal '__NSConstantString' tag type. - PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, - - /// The internal '__type_pack_element' template. - PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, -}; - -/// The number of declaration IDs that are predefined. -/// -/// For more information about predefined declarations, see the -/// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. -const unsigned int NUM_PREDEF_DECL_IDS = 18; - /// Record of updates for a declaration that was modified after /// being deserialized. This can occur within DECLTYPES_BLOCK_ID. const unsigned int DECL_UPDATES = 49; @@ -2002,7 +1926,7 @@ enum StmtCode { STMT_OMP_TARGET_TEAMS_GENERIC_LOOP_DIRECTIVE, STMT_OMP_PARALLEL_GENERIC_LOOP_DIRECTIVE, STMT_OMP_TARGET_PARALLEL_GENERIC_LOOP_DIRECTIVE, - EXPR_OMP_ARRAY_SECTION, + EXPR_ARRAY_SECTION, EXPR_OMP_ARRAY_SHAPING, EXPR_OMP_ITERATOR, @@ -2056,39 +1980,10 @@ enum CtorInitializerType { /// Kinds of cleanup objects owned by ExprWithCleanups. enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; -/// Describes the redeclarations of a declaration. -struct LocalRedeclarationsInfo { - // The ID of the first declaration - DeclID FirstID; - - // Offset into the array of redeclaration chains. - unsigned Offset; - - friend bool operator<(const LocalRedeclarationsInfo &X, - const LocalRedeclarationsInfo &Y) { - return X.FirstID < Y.FirstID; - } - - friend bool operator>(const LocalRedeclarationsInfo &X, - const LocalRedeclarationsInfo &Y) { - return X.FirstID > Y.FirstID; - } - - friend bool operator<=(const LocalRedeclarationsInfo &X, - const LocalRedeclarationsInfo &Y) { - return X.FirstID <= Y.FirstID; - } - - friend bool operator>=(const LocalRedeclarationsInfo &X, - const LocalRedeclarationsInfo &Y) { - return X.FirstID >= Y.FirstID; - } -}; - /// Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { // The ID of the definition - DeclID DefinitionID; + LocalDeclID DefinitionID; // Offset into the array of category lists. unsigned Offset; diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h index f3a01a4b9731..3ab7f1a91843 100644 --- a/clang/include/clang/Serialization/ASTDeserializationListener.h +++ b/clang/include/clang/Serialization/ASTDeserializationListener.h @@ -44,7 +44,7 @@ public: /// unqualified. virtual void TypeRead(serialization::TypeIdx Idx, QualType T) { } /// A decl was deserialized from the AST file. - virtual void DeclRead(serialization::DeclID ID, const Decl *D) { } + virtual void DeclRead(GlobalDeclID ID, const Decl *D) {} /// A selector was read from the AST file. virtual void SelectorRead(serialization::SelectorID iD, Selector Sel) {} /// A macro definition was read from the AST file. diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 1cd8b6a357cb..64f1ebc117b3 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -501,10 +501,7 @@ private: /// = I + 1 has already been loaded. llvm::PagedVector DeclsLoaded; - static_assert(std::is_same_v); - - using GlobalDeclMapType = - ContinuousRangeMap; + using GlobalDeclMapType = ContinuousRangeMap; /// Mapping from global declaration IDs to the module in which the /// declaration resides. @@ -512,16 +509,15 @@ private: using FileOffset = std::pair; using FileOffsetsTy = SmallVector; - using DeclUpdateOffsetsMap = - llvm::DenseMap; + using DeclUpdateOffsetsMap = llvm::DenseMap; /// Declarations that have modifications residing in a later file /// in the chain. DeclUpdateOffsetsMap DeclUpdateOffsets; - using DelayedNamespaceOffsetMapTy = llvm::DenseMap< - serialization::DeclID, - std::pair>; + using DelayedNamespaceOffsetMapTy = + llvm::DenseMap>; /// Mapping from global declaration IDs to the lexical and visible block /// offset for delayed namespace in reduced BMI. @@ -535,13 +531,12 @@ private: struct PendingUpdateRecord { Decl *D; - serialization::GlobalDeclID ID; + GlobalDeclID ID; // Whether the declaration was just deserialized. bool JustLoaded; - PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D, - bool JustLoaded) + PendingUpdateRecord(GlobalDeclID ID, Decl *D, bool JustLoaded) : D(D), ID(ID), JustLoaded(JustLoaded) {} }; @@ -594,10 +589,10 @@ private: struct FileDeclsInfo { ModuleFile *Mod = nullptr; - ArrayRef Decls; + ArrayRef Decls; FileDeclsInfo() = default; - FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) + FileDeclsInfo(ModuleFile *Mod, ArrayRef Decls) : Mod(Mod), Decls(Decls) {} }; @@ -606,7 +601,11 @@ private: /// An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - using LexicalContents = ArrayRef; + using unalighed_decl_id_t = + llvm::support::detail::packed_endian_specific_integral< + serialization::DeclID, llvm::endianness::native, + llvm::support::unaligned>; + using LexicalContents = ArrayRef; /// Map from a DeclContext to its lexical contents. llvm::DenseMap> @@ -631,8 +630,7 @@ private: /// Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. - llvm::DenseMap - PendingVisibleUpdates; + llvm::DenseMap PendingVisibleUpdates; /// The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. @@ -658,7 +656,7 @@ private: /// Read the record that describes the visible contents of a DC. bool ReadVisibleDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, - uint64_t Offset, serialization::DeclID ID); + uint64_t Offset, GlobalDeclID ID); /// A vector containing identifiers that have already been /// loaded. @@ -811,21 +809,26 @@ private: /// This contains the data loaded from all EAGERLY_DESERIALIZED_DECLS blocks /// in the chain. The referenced declarations are deserialized and passed to /// the consumer eagerly. - SmallVector EagerlyDeserializedDecls; + SmallVector EagerlyDeserializedDecls; /// The IDs of all tentative definitions stored in the chain. /// /// Sema keeps track of all tentative definitions in a TU because it has to /// complete them and pass them on to CodeGen. Thus, tentative definitions in /// the PCH chain must be eagerly deserialized. - SmallVector TentativeDefinitions; + SmallVector TentativeDefinitions; /// The IDs of all CXXRecordDecls stored in the chain whose VTables are /// used. /// /// CodeGen has to emit VTables for these records, so they have to be eagerly /// deserialized. - SmallVector VTableUses; + struct VTableUse { + GlobalDeclID ID; + SourceLocation::UIntTy RawLoc; + bool Used; + }; + SmallVector VTableUses; /// A snapshot of the pending instantiations in the chain. /// @@ -833,7 +836,11 @@ private: /// end of the TU. It consists of a pair of values for every pending /// instantiation where the first value is the ID of the decl and the second /// is the instantiation location. - SmallVector PendingInstantiations; + struct PendingInstantiation { + GlobalDeclID ID; + SourceLocation::UIntTy RawLoc; + }; + SmallVector PendingInstantiations; //@} @@ -843,11 +850,11 @@ private: /// A snapshot of Sema's unused file-scoped variable tracking, for /// generating warnings. - SmallVector UnusedFileScopedDecls; + SmallVector UnusedFileScopedDecls; /// A list of all the delegating constructors we've seen, to diagnose /// cycles. - SmallVector DelegatingCtorDecls; + SmallVector DelegatingCtorDecls; /// Method selectors used in a @selector expression. Used for /// implementation of -Wselector. @@ -860,7 +867,7 @@ private: /// The IDs of type aliases for ext_vectors that exist in the chain. /// /// Used by Sema for finding sugared names for ext_vectors in diagnostics. - SmallVector ExtVectorDecls; + SmallVector ExtVectorDecls; //@} @@ -871,7 +878,7 @@ private: /// The IDs of all potentially unused typedef names in the chain. /// /// Sema tracks these to emit warnings. - SmallVector UnusedLocalTypedefNameCandidates; + SmallVector UnusedLocalTypedefNameCandidates; /// Our current depth in #pragma cuda force_host_device begin/end /// macros. @@ -880,7 +887,7 @@ private: /// The IDs of the declarations Sema stores directly. /// /// Sema tracks a few important decls, such as namespace std, directly. - SmallVector SemaDeclRefs; + SmallVector SemaDeclRefs; /// The IDs of the types ASTContext stores directly. /// @@ -891,7 +898,7 @@ private: /// /// The AST context tracks a few important decls, currently cudaConfigureCall, /// directly. - SmallVector CUDASpecialDeclRefs; + SmallVector CUDASpecialDeclRefs; /// The floating point pragma option settings. SmallVector FPPragmaOptions; @@ -940,11 +947,15 @@ private: llvm::DenseMap> OpenCLDeclExtMap; /// A list of the namespaces we've seen. - SmallVector KnownNamespaces; + SmallVector KnownNamespaces; /// A list of undefined decls with internal linkage followed by the /// SourceLocation of a matching ODR-use. - SmallVector UndefinedButUsed; + struct UndefinedButUsedDecl { + GlobalDeclID ID; + SourceLocation::UIntTy RawLoc; + }; + SmallVector UndefinedButUsed; /// Delete expressions to analyze at the end of translation unit. SmallVector DelayedDeleteExprs; @@ -956,7 +967,7 @@ private: /// The IDs of all decls to be checked for deferred diags. /// /// Sema tracks these to emit deferred diags. - llvm::SmallSetVector DeclsToCheckForDeferredDiags; + llvm::SmallSetVector DeclsToCheckForDeferredDiags; private: struct ImportedSubmodule { @@ -1093,8 +1104,8 @@ private: /// /// The declarations on the identifier chain for these identifiers will be /// loaded once the recursive loading has completed. - llvm::MapVector> - PendingIdentifierInfos; + llvm::MapVector> + PendingIdentifierInfos; /// The set of lookup results that we have faked in order to support /// merging of partially deserialized decls but that we have not yet removed. @@ -1138,8 +1149,8 @@ private: /// been loaded but its DeclContext was not set yet. struct PendingDeclContextInfo { Decl *D; - serialization::GlobalDeclID SemaDC; - serialization::GlobalDeclID LexicalDC; + GlobalDeclID SemaDC; + GlobalDeclID LexicalDC; }; /// The set of Decls that have been loaded but their DeclContexts are @@ -1220,8 +1231,7 @@ private: /// module is loaded. SmallVector ObjCClassesLoaded; - using KeyDeclsMap = - llvm::DenseMap>; + using KeyDeclsMap = llvm::DenseMap>; /// A mapping from canonical declarations to the set of global /// declaration IDs for key declaration that have been merged with that @@ -1430,7 +1440,7 @@ private: QualType readTypeRecord(unsigned Index); RecordLocation TypeCursorForIndex(unsigned Index); void LoadedDecl(unsigned Index, Decl *D); - Decl *ReadDeclRecord(serialization::DeclID ID); + Decl *ReadDeclRecord(GlobalDeclID ID); void markIncompleteDeclChain(Decl *D); /// Returns the most recent declaration of a declaration (which must be @@ -1438,11 +1448,10 @@ private: /// merged into its redecl chain. Decl *getMostRecentExistingDecl(Decl *D); - RecordLocation DeclCursorForID(serialization::DeclID ID, - SourceLocation &Location); + RecordLocation DeclCursorForID(GlobalDeclID ID, SourceLocation &Location); void loadDeclUpdateRecords(PendingUpdateRecord &Record); void loadPendingDeclChain(Decl *D, uint64_t LocalOffset); - void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, + void loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration = 0); RecordLocation getLocalBitOffset(uint64_t GlobalOffset); @@ -1477,11 +1486,10 @@ private: unsigned ClientLoadCapabilities); public: - class ModuleDeclIterator - : public llvm::iterator_adaptor_base< - ModuleDeclIterator, const serialization::LocalDeclID *, - std::random_access_iterator_tag, const Decl *, ptrdiff_t, - const Decl *, const Decl *> { + class ModuleDeclIterator : public llvm::iterator_adaptor_base< + ModuleDeclIterator, const LocalDeclID *, + std::random_access_iterator_tag, const Decl *, + ptrdiff_t, const Decl *, const Decl *> { ASTReader *Reader = nullptr; ModuleFile *Mod = nullptr; @@ -1489,7 +1497,7 @@ public: ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, - const serialization::LocalDeclID *Pos) + const LocalDeclID *Pos) : iterator_adaptor_base(Pos), Reader(Reader), Mod(Mod) {} value_type operator*() const { @@ -1517,9 +1525,8 @@ private: void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name); - void addPendingDeclContextInfo(Decl *D, - serialization::GlobalDeclID SemaDC, - serialization::GlobalDeclID LexicalDC) { + void addPendingDeclContextInfo(Decl *D, GlobalDeclID SemaDC, + GlobalDeclID LexicalDC) { assert(D); PendingDeclContextInfo Info = { D, SemaDC, LexicalDC }; PendingDeclContextInfos.push_back(Info); @@ -1897,38 +1904,36 @@ public: /// Map from a local declaration ID within a given module to a /// global declaration ID. - serialization::DeclID getGlobalDeclID(ModuleFile &F, - serialization::LocalDeclID LocalID) const; + GlobalDeclID getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const; /// Returns true if global DeclID \p ID originated from module \p M. - bool isDeclIDFromModule(serialization::GlobalDeclID ID, ModuleFile &M) const; + bool isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const; /// Retrieve the module file that owns the given declaration, or NULL /// if the declaration is not from a module file. ModuleFile *getOwningModuleFile(const Decl *D); /// Returns the source location for the decl \p ID. - SourceLocation getSourceLocationForDeclID(serialization::GlobalDeclID ID); + SourceLocation getSourceLocationForDeclID(GlobalDeclID ID); /// Resolve a declaration ID into a declaration, potentially /// building a new declaration. - Decl *GetDecl(serialization::DeclID ID); - Decl *GetExternalDecl(uint32_t ID) override; + Decl *GetDecl(GlobalDeclID ID); + Decl *GetExternalDecl(GlobalDeclID ID) override; /// Resolve a declaration ID into a declaration. Return 0 if it's not /// been loaded yet. - Decl *GetExistingDecl(serialization::DeclID ID); + Decl *GetExistingDecl(GlobalDeclID ID); /// Reads a declaration with the given local ID in the given module. - Decl *GetLocalDecl(ModuleFile &F, uint32_t LocalID) { + Decl *GetLocalDecl(ModuleFile &F, LocalDeclID LocalID) { return GetDecl(getGlobalDeclID(F, LocalID)); } /// Reads a declaration with the given local ID in the given module. /// /// \returns The requested declaration, casted to the given return type. - template - T *GetLocalDeclAs(ModuleFile &F, uint32_t LocalID) { + template T *GetLocalDeclAs(ModuleFile &F, LocalDeclID LocalID) { return cast_or_null(GetLocalDecl(F, LocalID)); } @@ -1937,16 +1942,15 @@ public: /// /// \returns the global ID of the given declaration as known in the given /// module file. - serialization::DeclID - mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - serialization::DeclID GlobalID); + LocalDeclID mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID); /// Reads a declaration ID from the given position in a record in the /// given module. /// /// \returns The declaration ID read from the record, adjusted to a global ID. - serialization::DeclID ReadDeclID(ModuleFile &F, const RecordData &Record, - unsigned &Idx); + GlobalDeclID ReadDeclID(ModuleFile &F, const RecordData &Record, + unsigned &Idx); /// Reads a declaration from the given position in a record in the /// given module. @@ -2121,7 +2125,7 @@ public: void SetIdentifierInfo(unsigned ID, IdentifierInfo *II); void SetGloballyVisibleDecls(IdentifierInfo *II, - const SmallVectorImpl &DeclIDs, + const SmallVectorImpl &DeclIDs, SmallVectorImpl *Decls = nullptr); /// Report a diagnostic. @@ -2363,7 +2367,7 @@ public: // Contains the IDs for declarations that were requested before we have // access to a Sema object. - SmallVector PreloadedDeclIDs; + SmallVector PreloadedDeclIDs; /// Retrieve the semantic analysis object used to analyze the /// translation unit in which the precompiled header is being diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h index 7dd1140106e4..06b80f266a94 100644 --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -103,13 +103,6 @@ public: DC); } - /// Read the record that describes the visible contents of a DC. - bool readVisibleDeclContextStorage(uint64_t Offset, - serialization::DeclID ID) { - return Reader->ReadVisibleDeclContextStorage(*F, F->DeclsCursor, Offset, - ID); - } - ExplicitSpecifier readExplicitSpec() { uint64_t Kind = readInt(); bool HasExpr = Kind & 0x1; @@ -143,8 +136,7 @@ public: /// Reads a declaration with the given local ID in the given module. /// /// \returns The requested declaration, casted to the given return type. - template - T *GetLocalDeclAs(uint32_t LocalID) { + template T *GetLocalDeclAs(LocalDeclID LocalID) { return cast_or_null(Reader->GetLocalDecl(*F, LocalID)); } @@ -190,9 +182,7 @@ public: /// Reads a declaration ID from the given position in this record. /// /// \returns The declaration ID read from the record, adjusted to a global ID. - serialization::DeclID readDeclID() { - return Reader->ReadDeclID(*F, Record, Idx); - } + GlobalDeclID readDeclID() { return Reader->ReadDeclID(*F, Record, Idx); } /// Reads a declaration from the given position in a record in the /// given module, advancing Idx. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index 13b4ad4ad295..6c45b7348b85 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -212,10 +212,10 @@ private: llvm::SmallVector DelayedNamespace; /// The first ID number we can use for our own declarations. - serialization::DeclID FirstDeclID = serialization::NUM_PREDEF_DECL_IDS; + LocalDeclID FirstDeclID = LocalDeclID(clang::NUM_PREDEF_DECL_IDS); /// The decl ID that will be assigned to the next new decl. - serialization::DeclID NextDeclID = FirstDeclID; + LocalDeclID NextDeclID = FirstDeclID; /// Map that provides the ID numbers of each declaration within /// the output stream, as well as those deserialized from a chained PCH. @@ -223,7 +223,7 @@ private: /// The ID numbers of declarations are consecutive (in order of /// discovery) and start at 2. 1 is reserved for the translation /// unit, while 0 is reserved for NULL. - llvm::DenseMap DeclIDs; + llvm::DenseMap DeclIDs; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -233,9 +233,8 @@ private: /// are relative to this value. uint64_t DeclTypesBlockStartOffset = 0; - /// Sorted (by file offset) vector of pairs of file offset/DeclID. - using LocDeclIDsTy = - SmallVector, 64>; + /// Sorted (by file offset) vector of pairs of file offset/LocalDeclID. + using LocDeclIDsTy = SmallVector, 64>; struct DeclIDInFileInfo { LocDeclIDsTy DeclIDs; @@ -250,7 +249,7 @@ private: /// that it contains. FileDeclIDsTy FileDeclIDs; - void associateDeclWithFile(const Decl *D, serialization::DeclID); + void associateDeclWithFile(const Decl *D, LocalDeclID); /// The first ID number we can use for our own types. serialization::TypeID FirstTypeID = serialization::NUM_PREDEF_TYPE_IDS; @@ -421,8 +420,8 @@ private: /// headers. The declarations themselves are stored as declaration /// IDs, since they will be written out to an EAGERLY_DESERIALIZED_DECLS /// record. - SmallVector EagerlyDeserializedDecls; - SmallVector ModularCodegenDecls; + RecordData EagerlyDeserializedDecls; + RecordData ModularCodegenDecls; /// DeclContexts that have received extensions since their serialized /// form. @@ -709,7 +708,7 @@ public: return false; auto I = DeclIDs.find(D); return (I == DeclIDs.end() || - I->second >= serialization::NUM_PREDEF_DECL_IDS); + I->second.get() >= clang::NUM_PREDEF_DECL_IDS); }; /// Emit a reference to a declaration. @@ -717,12 +716,13 @@ public: // Emit a reference to a declaration if the declaration was emitted. void AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record); - /// Force a declaration to be emitted and get its ID. - serialization::DeclID GetDeclRef(const Decl *D); + /// Force a declaration to be emitted and get its local ID to the module file + /// been writing. + LocalDeclID GetDeclRef(const Decl *D); - /// Determine the declaration ID of an already-emitted + /// Determine the local declaration ID of an already-emitted /// declaration. - serialization::DeclID getDeclID(const Decl *D); + LocalDeclID getDeclID(const Decl *D); /// Whether or not the declaration got emitted. If not, it wouldn't be /// emitted. diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index bc0aa89966c2..25f644e76edb 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -462,7 +462,7 @@ public: serialization::DeclID BaseDeclID = 0; /// Remapping table for declaration IDs in this module. - ContinuousRangeMap DeclRemap; + ContinuousRangeMap DeclRemap; /// Mapping from the module files that this module file depends on /// to the base declaration ID for that module as it is understood within this @@ -474,7 +474,7 @@ public: llvm::DenseMap GlobalToLocalDeclIDs; /// Array of file-level DeclIDs sorted by file. - const serialization::DeclID *FileSortedDecls = nullptr; + const LocalDeclID *FileSortedDecls = nullptr; unsigned NumFileSortedDecls = 0; /// Array of category list location information within this diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index fac0c04ae2ca..ef23b160a3c0 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -225,15 +225,11 @@ public: /// invalidated. This should include any regions explicitly invalidated /// even if they do not currently have bindings. Pass \c NULL if this /// information will not be used. - virtual StoreRef invalidateRegions(Store store, - ArrayRef Values, - const Expr *E, unsigned Count, - const LocationContext *LCtx, - const CallEvent *Call, - InvalidatedSymbols &IS, - RegionAndSymbolInvalidationTraits &ITraits, - InvalidatedRegions *InvalidatedTopLevel, - InvalidatedRegions *Invalidated) = 0; + virtual StoreRef invalidateRegions( + Store store, ArrayRef Values, const Expr *Ex, unsigned Count, + const LocationContext *LCtx, const CallEvent *Call, + InvalidatedSymbols &IS, RegionAndSymbolInvalidationTraits &ITraits, + InvalidatedRegions *TopLevelRegions, InvalidatedRegions *Invalidated) = 0; /// enterStackFrame - Let the StoreManager to do something when execution /// engine is about to execute into a callee. diff --git a/clang/include/clang/Support/RISCVVIntrinsicUtils.h b/clang/include/clang/Support/RISCVVIntrinsicUtils.h index ef9d6c15724b..97493bae5656 100644 --- a/clang/include/clang/Support/RISCVVIntrinsicUtils.h +++ b/clang/include/clang/Support/RISCVVIntrinsicUtils.h @@ -502,7 +502,8 @@ enum RVVRequire : uint32_t { RVV_REQ_Zvksed = 1 << 14, RVV_REQ_Zvksh = 1 << 15, RVV_REQ_Zvfbfwma = 1 << 16, - RVV_REQ_Experimental = 1 << 17, + RVV_REQ_Zvfbfmin = 1 << 17, + RVV_REQ_Experimental = 1 << 18, LLVM_MARK_AS_BITMASK_ENUM(RVV_REQ_Experimental) }; diff --git a/clang/lib/APINotes/APINotesFormat.h b/clang/lib/APINotes/APINotesFormat.h index 615314c46f09..97e630e97fdc 100644 --- a/clang/lib/APINotes/APINotesFormat.h +++ b/clang/lib/APINotes/APINotesFormat.h @@ -24,7 +24,10 @@ const uint16_t VERSION_MAJOR = 0; /// API notes file minor version number. /// /// When the format changes IN ANY WAY, this number should be incremented. -const uint16_t VERSION_MINOR = 25; // SwiftImportAs +const uint16_t VERSION_MINOR = 26; // SwiftCopyable + +const uint8_t kSwiftCopyable = 1; +const uint8_t kSwiftNonCopyable = 2; using IdentifierID = llvm::PointerEmbeddedInt; using IdentifierIDField = llvm::BCVBR<16>; diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp index dfc3beb6fa13..b60ca685f62c 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -527,6 +527,13 @@ public: Info.EnumExtensibility = static_cast((Payload & 0x3) - 1); + uint8_t Copyable = + endian::readNext(Data); + if (Copyable == kSwiftNonCopyable) + Info.setSwiftCopyable(std::optional(false)); + else if (Copyable == kSwiftCopyable) + Info.setSwiftCopyable(std::optional(true)); + unsigned ImportAsLength = endian::readNext(Data); if (ImportAsLength > 0) { diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp index e3f5d102fcd0..3e6159763150 100644 --- a/clang/lib/APINotes/APINotesWriter.cpp +++ b/clang/lib/APINotes/APINotesWriter.cpp @@ -1128,7 +1128,7 @@ public: return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) + 2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) + 2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) + - 1 + getCommonTypeInfoSize(TI); + 2 + getCommonTypeInfoSize(TI); } void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) { @@ -1146,6 +1146,11 @@ public: writer.write(Flags); + if (auto Copyable = TI.isSwiftCopyable()) + writer.write(*Copyable ? kSwiftCopyable : kSwiftNonCopyable); + else + writer.write(0); + if (auto ImportAs = TI.SwiftImportAs) { writer.write(ImportAs->size() + 1); OS.write(ImportAs->c_str(), ImportAs->size()); diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 57d6da7a1775..2295d769d344 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -419,6 +419,7 @@ struct Tag { std::optional EnumExtensibility; std::optional FlagEnum; std::optional EnumConvenienceKind; + std::optional SwiftCopyable; }; typedef std::vector TagsSeq; @@ -452,6 +453,7 @@ template <> struct MappingTraits { IO.mapOptional("EnumExtensibility", T.EnumExtensibility); IO.mapOptional("FlagEnum", T.FlagEnum); IO.mapOptional("EnumKind", T.EnumConvenienceKind); + IO.mapOptional("SwiftCopyable", T.SwiftCopyable); } }; } // namespace yaml @@ -1009,6 +1011,9 @@ public: if (Tag.SwiftReleaseOp) TI.SwiftReleaseOp = Tag.SwiftReleaseOp; + if (Tag.SwiftCopyable) + TI.setSwiftCopyable(Tag.SwiftCopyable); + if (Tag.EnumConvenienceKind) { if (Tag.EnumExtensibility) { emitError( diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b36fb5523af5..cbf4932aff9a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1083,7 +1083,8 @@ void ASTContext::addModuleInitializer(Module *M, Decl *D) { Inits->Initializers.push_back(D); } -void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef IDs) { +void ASTContext::addLazyModuleInitializers(Module *M, + ArrayRef IDs) { auto *&Inits = ModuleInitializers[M]; if (!Inits) Inits = new (*this) PerModuleInitializers; @@ -1320,16 +1321,14 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, // Placeholder type for OMP array sections. if (LangOpts.OpenMP) { - InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); + InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection); InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping); InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator); } - // Placeholder type for OpenACC array sections. - if (LangOpts.OpenACC) { - // FIXME: Once we implement OpenACC array sections in Sema, this will either - // be combined with the OpenMP type, or given its own type. In the meantime, - // just use the OpenMP type so that parsing can work. - InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection); + // Placeholder type for OpenACC array sections, if we are ALSO in OMP mode, + // don't bother, as we're just using the same type as OMP. + if (LangOpts.OpenACC && !LangOpts.OpenMP) { + InitBuiltinType(ArraySectionTy, BuiltinType::ArraySection); } if (LangOpts.MatrixTypes) InitBuiltinType(IncompleteMatrixIdxTy, BuiltinType::IncompleteMatrixIdx); diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp index 5ec3013fabba..bad8e75b2f87 100644 --- a/clang/lib/AST/ComputeDependence.cpp +++ b/clang/lib/AST/ComputeDependence.cpp @@ -443,12 +443,17 @@ ExprDependence clang::computeDependence(ObjCIndirectCopyRestoreExpr *E) { return E->getSubExpr()->getDependence(); } -ExprDependence clang::computeDependence(OMPArraySectionExpr *E) { +ExprDependence clang::computeDependence(ArraySectionExpr *E) { auto D = E->getBase()->getDependence(); if (auto *LB = E->getLowerBound()) D |= LB->getDependence(); if (auto *Len = E->getLength()) D |= Len->getDependence(); + + if (E->isOMPArraySection()) { + if (auto *Stride = E->getStride()) + D |= Stride->getDependence(); + } return D; } diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 474e0ccde5bb..e7e95c16b697 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2151,7 +2151,7 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartL, return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S); } -VarDecl *VarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +VarDecl *VarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None); @@ -2929,7 +2929,7 @@ QualType ParmVarDecl::getOriginalType() const { return T; } -ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, SC_None, nullptr); @@ -4553,7 +4553,7 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC, BW, Mutable, InitStyle); } -FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, nullptr, false, ICIS_NoInit); @@ -4863,7 +4863,7 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, return Enum; } -EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { EnumDecl *Enum = new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr, false, false, false); @@ -5025,7 +5025,8 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC, return R; } -RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, + GlobalDeclID ID) { RecordDecl *R = new (C, ID) RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -5297,7 +5298,7 @@ PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C, } PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + GlobalDeclID ID, unsigned ArgSize) { return new (C, ID, additionalSizeToAlloc(ArgSize + 1)) PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown); @@ -5322,7 +5323,7 @@ PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC, } PragmaDetectMismatchDecl * -PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NameValueSize) { return new (C, ID, additionalSizeToAlloc(NameValueSize + 1)) PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0); @@ -5349,7 +5350,7 @@ LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL); } -LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation()); } @@ -5390,7 +5391,7 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, QualType Type, } ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ImplicitParamDecl(C, QualType(), ImplicitParamKind::Other); } @@ -5408,7 +5409,7 @@ FunctionDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, return New; } -FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionDecl( Function, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -5418,7 +5419,7 @@ BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) BlockDecl(DC, L); } -BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BlockDecl(nullptr, SourceLocation()); } @@ -5432,7 +5433,7 @@ CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC, CapturedDecl(DC, NumParams); } -CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumParams) { return new (C, ID, additionalSizeToAlloc(NumParams)) CapturedDecl(nullptr, NumParams); @@ -5458,8 +5459,8 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, return new (C, CD) EnumConstantDecl(C, CD, L, Id, T, E, V); } -EnumConstantDecl * -EnumConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EnumConstantDecl *EnumConstantDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) EnumConstantDecl(C, nullptr, SourceLocation(), nullptr, QualType(), nullptr, llvm::APSInt()); } @@ -5486,7 +5487,7 @@ IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) IndirectFieldDecl(C, nullptr, SourceLocation(), DeclarationName(), QualType(), std::nullopt); @@ -5547,7 +5548,7 @@ bool TypedefNameDecl::isTransparentTagSlow() const { return isTransparent; } -TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5560,7 +5561,8 @@ TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo); } -TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); } @@ -5591,7 +5593,7 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, } FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -5609,7 +5611,7 @@ TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) { } TopLevelStmtDecl *TopLevelStmtDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) TopLevelStmtDecl(/*DC=*/nullptr, SourceLocation(), /*S=*/nullptr); } @@ -5630,7 +5632,7 @@ EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { return new (C, DC) EmptyDecl(DC, L); } -EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) EmptyDecl(nullptr, SourceLocation()); } @@ -5663,7 +5665,8 @@ HLSLBufferDecl *HLSLBufferDecl::Create(ASTContext &C, return Result; } -HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +HLSLBufferDecl *HLSLBufferDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) HLSLBufferDecl(nullptr, false, SourceLocation(), nullptr, SourceLocation(), SourceLocation()); } @@ -5719,7 +5722,7 @@ ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC, return Import; } -ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumLocations) { return new (C, ID, additionalSizeToAlloc(NumLocations)) ImportDecl(EmptyShell()); @@ -5752,6 +5755,6 @@ ExportDecl *ExportDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) ExportDecl(DC, ExportLoc); } -ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 7cb6b31c541f..f341c74cf86e 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -71,7 +71,7 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const { #include "clang/AST/DeclNodes.inc" void *Decl::operator new(std::size_t Size, const ASTContext &Context, - Decl::DeclID ID, std::size_t Extra) { + GlobalDeclID ID, std::size_t Extra) { // Allocate an extra 8 bytes worth of storage, which ensures that the // resulting pointer will still be 8-byte aligned. static_assert(sizeof(unsigned) * 2 >= alignof(Decl), @@ -85,7 +85,7 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Context, PrefixPtr[0] = 0; // Store the global declaration ID in the second 4 bytes. - PrefixPtr[1] = ID; + PrefixPtr[1] = ID.get(); return Result; } @@ -1115,7 +1115,9 @@ int64_t Decl::getID() const { const FunctionType *Decl::getFunctionType(bool BlocksToo) const { QualType Ty; - if (const auto *D = dyn_cast(this)) + if (const auto *D = dyn_cast(this)) + return nullptr; + else if (const auto *D = dyn_cast(this)) Ty = D->getType(); else if (const auto *D = dyn_cast(this)) Ty = D->getUnderlyingType(); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 426c52620510..75c441293d62 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -57,7 +57,8 @@ using namespace clang; void AccessSpecDecl::anchor() {} -AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) AccessSpecDecl(EmptyShell()); } @@ -68,7 +69,7 @@ void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const { for (ASTUnresolvedSet::iterator I = Impl.begin(); I != Impl.end(); ++I) I.setDecl(cast(Source->GetExternalDecl( - reinterpret_cast(I.getDecl()) >> 2))); + GlobalDeclID(reinterpret_cast(I.getDecl()) >> 2)))); Impl.Decls.setLazy(false); } @@ -160,8 +161,8 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC, return R; } -CXXRecordDecl * -CXXRecordDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C, + GlobalDeclID ID) { auto *R = new (C, ID) CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr, SourceLocation(), SourceLocation(), nullptr, nullptr); @@ -2162,8 +2163,8 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create( TInfo, EndLocation, Ctor, Kind); } -CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +CXXDeductionGuideDecl * +CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) CXXDeductionGuideDecl( C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(), QualType(), nullptr, SourceLocation(), nullptr, @@ -2175,8 +2176,8 @@ RequiresExprBodyDecl *RequiresExprBodyDecl::Create( return new (C, DC) RequiresExprBodyDecl(C, DC, StartLoc); } -RequiresExprBodyDecl *RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +RequiresExprBodyDecl * +RequiresExprBodyDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) RequiresExprBodyDecl(C, nullptr, SourceLocation()); } @@ -2281,7 +2282,8 @@ CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, isInline, ConstexprKind, EndLocation, TrailingRequiresClause); } -CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) CXXMethodDecl( CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, SC_None, false, false, @@ -2699,7 +2701,7 @@ CXXConstructorDecl::CXXConstructorDecl( void CXXConstructorDecl::anchor() {} CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + GlobalDeclID ID, uint64_t AllocKind) { bool hasTrailingExplicit = static_cast(AllocKind & TAKHasTailExplicit); bool isInheritingConstructor = @@ -2845,8 +2847,8 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const { void CXXDestructorDecl::anchor() {} -CXXDestructorDecl * -CXXDestructorDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXDestructorDecl *CXXDestructorDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) CXXDestructorDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, false, ConstexprSpecKind::Unspecified, nullptr); @@ -2877,8 +2879,8 @@ void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) { void CXXConversionDecl::anchor() {} -CXXConversionDecl * -CXXConversionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +CXXConversionDecl *CXXConversionDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) CXXConversionDecl( C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr, false, false, ExplicitSpecifier(), ConstexprSpecKind::Unspecified, @@ -2924,7 +2926,7 @@ LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, } LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) LinkageSpecDecl(nullptr, SourceLocation(), SourceLocation(), LinkageSpecLanguageIDs::C, false); @@ -2946,7 +2948,7 @@ UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC, } UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) UsingDirectiveDecl(nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), @@ -2985,7 +2987,8 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, NamespaceDecl(C, DC, Inline, StartLoc, IdLoc, Id, PrevDecl, Nested); } -NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +NamespaceDecl *NamespaceDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) NamespaceDecl(C, nullptr, false, SourceLocation(), SourceLocation(), nullptr, nullptr, false); } @@ -3046,8 +3049,8 @@ NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC, QualifierLoc, IdentLoc, Namespace); } -NamespaceAliasDecl * -NamespaceAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +NamespaceAliasDecl *NamespaceAliasDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) NamespaceAliasDecl(C, nullptr, SourceLocation(), SourceLocation(), nullptr, NestedNameSpecifierLoc(), @@ -3102,8 +3105,8 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty) : NamedDecl(K, nullptr, SourceLocation(), DeclarationName()), redeclarable_base(C) {} -UsingShadowDecl * -UsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingShadowDecl *UsingShadowDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingShadowDecl(UsingShadow, C, EmptyShell()); } @@ -3126,7 +3129,7 @@ ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC, } ConstructorUsingShadowDecl * -ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ConstructorUsingShadowDecl(C, EmptyShell()); } @@ -3174,7 +3177,7 @@ UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation UL, return new (C, DC) UsingDecl(DC, UL, QualifierLoc, NameInfo, HasTypename); } -UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingDecl *UsingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UsingDecl(nullptr, SourceLocation(), NestedNameSpecifierLoc(), DeclarationNameInfo(), false); @@ -3198,7 +3201,8 @@ UsingEnumDecl *UsingEnumDecl::Create(ASTContext &C, DeclContext *DC, UsingEnumDecl(DC, EnumType->getType()->getAsTagDecl()->getDeclName(), UL, EL, NL, EnumType); } -UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UsingEnumDecl *UsingEnumDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UsingEnumDecl(nullptr, DeclarationName(), SourceLocation(), SourceLocation(), SourceLocation(), nullptr); @@ -3217,7 +3221,7 @@ UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC, Extra) UsingPackDecl(DC, InstantiatedFrom, UsingDecls); } -UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { size_t Extra = additionalSizeToAlloc(NumExpansions); auto *Result = @@ -3243,7 +3247,7 @@ UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingValueDecl * -UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnresolvedUsingValueDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnresolvedUsingValueDecl(nullptr, QualType(), SourceLocation(), NestedNameSpecifierLoc(), @@ -3273,7 +3277,8 @@ UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC, } UnresolvedUsingTypenameDecl * -UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) UnresolvedUsingTypenameDecl( nullptr, SourceLocation(), SourceLocation(), NestedNameSpecifierLoc(), SourceLocation(), nullptr, SourceLocation()); @@ -3286,7 +3291,8 @@ UnresolvedUsingIfExistsDecl::Create(ASTContext &Ctx, DeclContext *DC, } UnresolvedUsingIfExistsDecl * -UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, Decl::DeclID ID) { +UnresolvedUsingIfExistsDecl::CreateDeserialized(ASTContext &Ctx, + GlobalDeclID ID) { return new (Ctx, ID) UnresolvedUsingIfExistsDecl(nullptr, SourceLocation(), DeclarationName()); } @@ -3310,7 +3316,7 @@ StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC, } StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) StaticAssertDecl(nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), false); } @@ -3332,7 +3338,7 @@ BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, return new (C, DC) BindingDecl(DC, IdLoc, Id); } -BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); } @@ -3363,7 +3369,7 @@ DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, } DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + GlobalDeclID ID, unsigned NumBindings) { size_t Extra = additionalSizeToAlloc(NumBindings); auto *Result = new (C, ID, Extra) @@ -3402,7 +3408,7 @@ MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, } MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) MSPropertyDecl(nullptr, SourceLocation(), DeclarationName(), QualType(), nullptr, SourceLocation(), nullptr, nullptr); @@ -3419,7 +3425,7 @@ MSGuidDecl *MSGuidDecl::Create(const ASTContext &C, QualType T, Parts P) { return new (C, DC) MSGuidDecl(DC, T, P); } -MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts()); } @@ -3529,7 +3535,7 @@ UnnamedGlobalConstantDecl::Create(const ASTContext &C, QualType T, } UnnamedGlobalConstantDecl * -UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue()); } diff --git a/clang/lib/AST/DeclFriend.cpp b/clang/lib/AST/DeclFriend.cpp index 1fabf8aa80c2..04b9b93699f3 100644 --- a/clang/lib/AST/DeclFriend.cpp +++ b/clang/lib/AST/DeclFriend.cpp @@ -62,7 +62,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned FriendTypeNumTPLists) { std::size_t Extra = additionalSizeToAlloc(FriendTypeNumTPLists); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index d4275eea0582..83062b0e6887 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -862,7 +862,8 @@ ObjCMethodDecl *ObjCMethodDecl::Create( isImplicitlyDeclared, isDefined, impControl, HasRelatedResultType); } -ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCMethodDecl *ObjCMethodDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) ObjCMethodDecl(SourceLocation(), SourceLocation(), Selector(), QualType(), nullptr, nullptr); } @@ -1486,7 +1487,7 @@ ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc, } ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (ctx, ID) ObjCTypeParamDecl(ctx, nullptr, ObjCTypeParamVariance::Invariant, SourceLocation(), 0, SourceLocation(), @@ -1551,7 +1552,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create( } ObjCInterfaceDecl *ObjCInterfaceDecl::CreateDeserialized(const ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ObjCInterfaceDecl(C, nullptr, SourceLocation(), nullptr, nullptr, SourceLocation(), nullptr, false); @@ -1865,7 +1866,7 @@ ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC, synthesized); } -ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCIvarDecl *ObjCIvarDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCIvarDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr, ObjCIvarDecl::None, nullptr, false); @@ -1914,7 +1915,7 @@ ObjCAtDefsFieldDecl } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCAtDefsFieldDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, QualType(), nullptr); @@ -1949,7 +1950,7 @@ ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, } ObjCProtocolDecl *ObjCProtocolDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { ObjCProtocolDecl *Result = new (C, ID) ObjCProtocolDecl(C, nullptr, nullptr, SourceLocation(), SourceLocation(), nullptr); @@ -2148,7 +2149,7 @@ ObjCCategoryDecl *ObjCCategoryDecl::Create( } ObjCCategoryDecl *ObjCCategoryDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCCategoryDecl(nullptr, SourceLocation(), SourceLocation(), SourceLocation(), nullptr, nullptr, nullptr); @@ -2188,8 +2189,8 @@ ObjCCategoryImplDecl *ObjCCategoryImplDecl::Create( atStartLoc, CategoryNameLoc); } -ObjCCategoryImplDecl *ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +ObjCCategoryImplDecl * +ObjCCategoryImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCategoryImplDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation(), SourceLocation()); @@ -2296,7 +2297,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, } ObjCImplementationDecl * -ObjCImplementationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCImplementationDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCImplementationDecl(nullptr, nullptr, nullptr, SourceLocation(), SourceLocation()); } @@ -2339,7 +2340,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, } ObjCCompatibleAliasDecl * -ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr); } @@ -2360,7 +2361,7 @@ ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, } ObjCPropertyDecl *ObjCPropertyDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ObjCPropertyDecl(nullptr, SourceLocation(), nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, None); @@ -2392,8 +2393,8 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, ivarLoc); } -ObjCPropertyImplDecl *ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +ObjCPropertyImplDecl * +ObjCPropertyImplDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) ObjCPropertyImplDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, Dynamic, nullptr, SourceLocation()); diff --git a/clang/lib/AST/DeclOpenMP.cpp b/clang/lib/AST/DeclOpenMP.cpp index b178a15aab5f..81ca48e60942 100644 --- a/clang/lib/AST/DeclOpenMP.cpp +++ b/clang/lib/AST/DeclOpenMP.cpp @@ -36,7 +36,7 @@ OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C, } OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + GlobalDeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, 0, N); @@ -63,7 +63,8 @@ OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC, return D; } -OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned NVars, unsigned NClauses) { return OMPDeclarativeDirective::createEmptyDirective( @@ -89,7 +90,8 @@ OMPRequiresDecl *OMPRequiresDecl::Create(ASTContext &C, DeclContext *DC, L); } -OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +OMPRequiresDecl *OMPRequiresDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 0, SourceLocation()); @@ -117,7 +119,7 @@ OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create( } OMPDeclareReductionDecl * -OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +OMPDeclareReductionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) OMPDeclareReductionDecl( OMPDeclareReduction, /*DC=*/nullptr, SourceLocation(), DeclarationName(), QualType(), /*PrevDeclInScope=*/nullptr); @@ -148,7 +150,7 @@ OMPDeclareMapperDecl *OMPDeclareMapperDecl::Create( } OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID, + GlobalDeclID ID, unsigned N) { return OMPDeclarativeDirective::createEmptyDirective( C, ID, N, 1, SourceLocation(), DeclarationName(), QualType(), @@ -179,7 +181,7 @@ OMPCapturedExprDecl *OMPCapturedExprDecl::Create(ASTContext &C, DeclContext *DC, } OMPCapturedExprDecl *OMPCapturedExprDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) OMPCapturedExprDecl(C, nullptr, nullptr, QualType(), /*TInfo=*/nullptr, SourceLocation()); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 0ba271c3e04e..d27a30e0c5fc 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -337,9 +337,10 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (CommonBasePtr->LazySpecializations) { ASTContext &Context = getASTContext(); - uint32_t *Specs = CommonBasePtr->LazySpecializations; + GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; CommonBasePtr->LazySpecializations = nullptr; - for (uint32_t I = 0, N = *Specs++; I != N; ++I) + unsigned SpecSize = (*Specs++).get(); + for (unsigned I = 0; I != SpecSize; ++I) (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); } } @@ -417,8 +418,8 @@ FunctionTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -FunctionTemplateDecl *FunctionTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +FunctionTemplateDecl * +FunctionTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) FunctionTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -503,7 +504,7 @@ ClassTemplateDecl *ClassTemplateDecl::Create(ASTContext &C, DeclContext *DC, } ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) ClassTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -652,14 +653,14 @@ TemplateTypeParmDecl *TemplateTypeParmDecl::Create( } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID) { +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTypeParmDecl(nullptr, SourceLocation(), SourceLocation(), nullptr, false, false, std::nullopt); } TemplateTypeParmDecl * -TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, Decl::DeclID ID, +TemplateTypeParmDecl::CreateDeserialized(const ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc(HasTypeConstraint ? 1 : 0)) @@ -759,7 +760,7 @@ NonTypeTemplateParmDecl *NonTypeTemplateParmDecl::Create( } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, bool HasTypeConstraint) { return new (C, ID, additionalSizeToAlloc, @@ -770,7 +771,7 @@ NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, } NonTypeTemplateParmDecl * -NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +NonTypeTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpandedTypes, bool HasTypeConstraint) { auto *NTTP = @@ -836,13 +837,13 @@ TemplateTemplateParmDecl::Create(const ASTContext &C, DeclContext *DC, } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TemplateTemplateParmDecl(nullptr, SourceLocation(), 0, 0, false, nullptr, false, nullptr); } TemplateTemplateParmDecl * -TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID, +TemplateTemplateParmDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID, unsigned NumExpansions) { auto *TTP = new (C, ID, additionalSizeToAlloc(NumExpansions)) @@ -949,7 +950,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); Result->setMayHaveOutOfDateDef(false); @@ -1035,8 +1036,7 @@ ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC, return TD; } -ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); @@ -1070,7 +1070,7 @@ ImplicitConceptSpecializationDecl *ImplicitConceptSpecializationDecl::Create( ImplicitConceptSpecializationDecl * ImplicitConceptSpecializationDecl::CreateDeserialized( - const ASTContext &C, Decl::DeclID ID, unsigned NumTemplateArgs) { + const ASTContext &C, GlobalDeclID ID, unsigned NumTemplateArgs) { return new (C, ID, additionalSizeToAlloc(NumTemplateArgs)) ImplicitConceptSpecializationDecl(EmptyShell{}, NumTemplateArgs); } @@ -1133,7 +1133,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); Result->setMayHaveOutOfDateDef(false); return Result; @@ -1160,7 +1160,7 @@ FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC, } FriendTemplateDecl *FriendTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) FriendTemplateDecl(EmptyShell()); } @@ -1179,8 +1179,8 @@ TypeAliasTemplateDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, return TD; } -TypeAliasTemplateDecl *TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { +TypeAliasTemplateDecl * +TypeAliasTemplateDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { return new (C, ID) TypeAliasTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1218,7 +1218,7 @@ VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC, } VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) VarTemplateDecl(C, nullptr, SourceLocation(), DeclarationName(), nullptr, nullptr); } @@ -1340,7 +1340,8 @@ VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create( } VarTemplateSpecializationDecl * -VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +VarTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, + GlobalDeclID ID) { return new (C, ID) VarTemplateSpecializationDecl(VarTemplateSpecialization, C); } @@ -1432,7 +1433,7 @@ VarTemplatePartialSpecializationDecl::Create( VarTemplatePartialSpecializationDecl * VarTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, - Decl::DeclID ID) { + GlobalDeclID ID) { return new (C, ID) VarTemplatePartialSpecializationDecl(C); } @@ -1546,7 +1547,7 @@ TemplateParamObjectDecl *TemplateParamObjectDecl::Create(const ASTContext &C, } TemplateParamObjectDecl * -TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, Decl::DeclID ID) { +TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) { auto *TPOD = new (C, ID) TemplateParamObjectDecl(nullptr, QualType(), APValue()); C.addDestruction(&TPOD->Value); return TPOD; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9eec7edc9d1a..63dcdb919c71 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3680,7 +3680,7 @@ bool Expr::HasSideEffects(const ASTContext &Ctx, case ParenExprClass: case ArraySubscriptExprClass: case MatrixSubscriptExprClass: - case OMPArraySectionExprClass: + case ArraySectionExprClass: case OMPArrayShapingExprClass: case OMPIteratorExprClass: case MemberExprClass: @@ -5060,9 +5060,9 @@ QualType AtomicExpr::getValueType() const { return T; } -QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) { +QualType ArraySectionExpr::getBaseOriginalType(const Expr *Base) { unsigned ArraySectionCount = 0; - while (auto *OASE = dyn_cast(Base->IgnoreParens())) { + while (auto *OASE = dyn_cast(Base->IgnoreParens())) { Base = OASE->getBase(); ++ArraySectionCount; } diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 7026fca8554c..2bb8f9aeedc7 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -145,7 +145,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::FunctionParmPackExprClass: case Expr::MSPropertyRefExprClass: case Expr::MSPropertySubscriptExprClass: - case Expr::OMPArraySectionExprClass: + case Expr::ArraySectionExprClass: case Expr::OMPArrayShapingExprClass: case Expr::OMPIteratorExprClass: return Cl::CL_LValue; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index de3c2a63913e..f1aa19e4409e 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2706,7 +2706,11 @@ static bool checkFloatingPointResult(EvalInfo &Info, const Expr *E, static bool HandleFloatToFloatCast(EvalInfo &Info, const Expr *E, QualType SrcType, QualType DestType, APFloat &Result) { - assert(isa(E) || isa(E)); + assert((isa(E) || isa(E) || + isa(E)) && + "HandleFloatToFloatCast has been checked with only CastExpr, " + "CompoundAssignOperator and ConvertVectorExpr. Please either validate " + "the new expression or address the root cause of this usage."); llvm::RoundingMode RM = getActiveRoundingMode(Info, E); APFloat::opStatus St; APFloat Value = Result; @@ -9237,9 +9241,10 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) { bool HasValidResult = !Result.InvalidBase && !Result.Designator.Invalid && !Result.IsNullPtr; bool VoidPtrCastMaybeOK = - HasValidResult && - Info.Ctx.hasSameUnqualifiedType(Result.Designator.getType(Info.Ctx), - E->getType()->getPointeeType()); + Result.IsNullPtr || + (HasValidResult && + Info.Ctx.hasSimilarType(Result.Designator.getType(Info.Ctx), + E->getType()->getPointeeType())); // 1. We'll allow it in std::allocator::allocate, and anything which that // calls. // 2. HACK 2022-03-28: Work around an issue with libstdc++'s @@ -10709,8 +10714,11 @@ namespace { bool VisitUnaryImag(const UnaryOperator *E); bool VisitBinaryOperator(const BinaryOperator *E); bool VisitUnaryOperator(const UnaryOperator *E); + bool VisitConvertVectorExpr(const ConvertVectorExpr *E); + bool VisitShuffleVectorExpr(const ShuffleVectorExpr *E); + // FIXME: Missing: conditional operator (for GNU - // conditional select), shufflevector, ExtVectorElementExpr + // conditional select), ExtVectorElementExpr }; } // end anonymous namespace @@ -10961,6 +10969,122 @@ bool VectorExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { return Success(APValue(ResultElements.data(), ResultElements.size()), E); } +static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO, + const Expr *E, QualType SourceTy, + QualType DestTy, APValue const &Original, + APValue &Result) { + if (SourceTy->isIntegerType()) { + if (DestTy->isRealFloatingType()) { + Result = APValue(APFloat(0.0)); + return HandleIntToFloatCast(Info, E, FPO, SourceTy, Original.getInt(), + DestTy, Result.getFloat()); + } + if (DestTy->isIntegerType()) { + Result = APValue( + HandleIntToIntCast(Info, E, DestTy, SourceTy, Original.getInt())); + return true; + } + } else if (SourceTy->isRealFloatingType()) { + if (DestTy->isRealFloatingType()) { + Result = Original; + return HandleFloatToFloatCast(Info, E, SourceTy, DestTy, + Result.getFloat()); + } + if (DestTy->isIntegerType()) { + Result = APValue(APSInt()); + return HandleFloatToIntCast(Info, E, SourceTy, Original.getFloat(), + DestTy, Result.getInt()); + } + } + + Info.FFDiag(E, diag::err_convertvector_constexpr_unsupported_vector_cast) + << SourceTy << DestTy; + return false; +} + +bool VectorExprEvaluator::VisitConvertVectorExpr(const ConvertVectorExpr *E) { + APValue Source; + QualType SourceVecType = E->getSrcExpr()->getType(); + if (!EvaluateAsRValue(Info, E->getSrcExpr(), Source)) + return false; + + QualType DestTy = E->getType()->castAs()->getElementType(); + QualType SourceTy = SourceVecType->castAs()->getElementType(); + + const FPOptions FPO = E->getFPFeaturesInEffect(Info.Ctx.getLangOpts()); + + auto SourceLen = Source.getVectorLength(); + SmallVector ResultElements; + ResultElements.reserve(SourceLen); + for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { + APValue Elt; + if (!handleVectorElementCast(Info, FPO, E, SourceTy, DestTy, + Source.getVectorElt(EltNum), Elt)) + return false; + ResultElements.push_back(std::move(Elt)); + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); +} + +static bool handleVectorShuffle(EvalInfo &Info, const ShuffleVectorExpr *E, + QualType ElemType, APValue const &VecVal1, + APValue const &VecVal2, unsigned EltNum, + APValue &Result) { + unsigned const TotalElementsInInputVector1 = VecVal1.getVectorLength(); + unsigned const TotalElementsInInputVector2 = VecVal2.getVectorLength(); + + APSInt IndexVal = E->getShuffleMaskIdx(Info.Ctx, EltNum); + int64_t index = IndexVal.getExtValue(); + // The spec says that -1 should be treated as undef for optimizations, + // but in constexpr we'd have to produce an APValue::Indeterminate, + // which is prohibited from being a top-level constant value. Emit a + // diagnostic instead. + if (index == -1) { + Info.FFDiag( + E, diag::err_shufflevector_minus_one_is_undefined_behavior_constexpr) + << EltNum; + return false; + } + + if (index < 0 || + index >= TotalElementsInInputVector1 + TotalElementsInInputVector2) + llvm_unreachable("Out of bounds shuffle index"); + + if (index >= TotalElementsInInputVector1) + Result = VecVal2.getVectorElt(index - TotalElementsInInputVector1); + else + Result = VecVal1.getVectorElt(index); + return true; +} + +bool VectorExprEvaluator::VisitShuffleVectorExpr(const ShuffleVectorExpr *E) { + APValue VecVal1; + const Expr *Vec1 = E->getExpr(0); + if (!EvaluateAsRValue(Info, Vec1, VecVal1)) + return false; + APValue VecVal2; + const Expr *Vec2 = E->getExpr(1); + if (!EvaluateAsRValue(Info, Vec2, VecVal2)) + return false; + + VectorType const *DestVecTy = E->getType()->castAs(); + QualType DestElTy = DestVecTy->getElementType(); + + auto TotalElementsInOutputVector = DestVecTy->getNumElements(); + + SmallVector ResultElements; + ResultElements.reserve(TotalElementsInOutputVector); + for (unsigned EltNum = 0; EltNum < TotalElementsInOutputVector; ++EltNum) { + APValue Elt; + if (!handleVectorShuffle(Info, E, DestElTy, VecVal1, VecVal2, EltNum, Elt)) + return false; + ResultElements.push_back(std::move(Elt)); + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); +} + //===----------------------------------------------------------------------===// // Array Evaluation //===----------------------------------------------------------------------===// @@ -16130,7 +16254,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { case Expr::StringLiteralClass: case Expr::ArraySubscriptExprClass: case Expr::MatrixSubscriptExprClass: - case Expr::OMPArraySectionExprClass: + case Expr::ArraySectionExprClass: case Expr::OMPArrayShapingExprClass: case Expr::OMPIteratorExprClass: case Expr::MemberExprClass: diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 090ef02aa422..e96a47496851 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -68,9 +68,7 @@ bool ExternalASTSource::layoutRecordType( return false; } -Decl *ExternalASTSource::GetExternalDecl(uint32_t ID) { - return nullptr; -} +Decl *ExternalASTSource::GetExternalDecl(GlobalDeclID ID) { return nullptr; } Selector ExternalASTSource::GetExternalSelector(uint32_t ID) { return Selector(); diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 8cd0c198d9a8..17f95e7f3cac 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -110,18 +110,37 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; - unsigned DerivedOffset = collectBaseOffset(getRecordTy(CE->getType()), - getRecordTy(SubExpr->getType())); + const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * { + if (const auto *PT = dyn_cast(Ty)) + return PT->getPointeeType()->getAsCXXRecordDecl(); + return Ty->getAsCXXRecordDecl(); + }; + + // FIXME: We can express a series of non-virtual casts as a single + // GetPtrBasePop op. + QualType CurType = SubExpr->getType(); + for (const CXXBaseSpecifier *B : CE->path()) { + if (B->isVirtual()) { + if (!this->emitGetPtrVirtBasePop(extractRecordDecl(B->getType()), CE)) + return false; + CurType = B->getType(); + } else { + unsigned DerivedOffset = collectBaseOffset(B->getType(), CurType); + if (!this->emitGetPtrBasePop(DerivedOffset, CE)) + return false; + CurType = B->getType(); + } + } - return this->emitGetPtrBasePop(DerivedOffset, CE); + return true; } case CK_BaseToDerived: { if (!this->visit(SubExpr)) return false; - unsigned DerivedOffset = collectBaseOffset(getRecordTy(SubExpr->getType()), - getRecordTy(CE->getType())); + unsigned DerivedOffset = + collectBaseOffset(SubExpr->getType(), CE->getType()); return this->emitGetPtrDerivedPop(DerivedOffset, CE); } @@ -193,6 +212,13 @@ bool ByteCodeExprGen::VisitCastExpr(const CastExpr *CE) { if (!this->visit(SubExpr)) return false; + // If SubExpr doesn't result in a pointer, make it one. + if (PrimType FromT = classifyPrim(SubExpr->getType()); FromT != PT_Ptr) { + assert(isPtrType(FromT)); + if (!this->emitDecayPtr(FromT, PT_Ptr, CE)) + return false; + } + PrimType T = classifyPrim(CE->getType()); if (T == PT_IntAP) return this->emitCastPointerIntegralAP(Ctx.getBitWidth(CE->getType()), @@ -905,8 +931,31 @@ bool ByteCodeExprGen::VisitImplicitValueInitExpr(const ImplicitValueIni if (std::optional T = classify(QT)) return this->visitZeroInitializer(*T, QT, E); - if (QT->isRecordType()) - return false; + if (QT->isRecordType()) { + const RecordDecl *RD = QT->getAsRecordDecl(); + assert(RD); + if (RD->isInvalidDecl()) + return false; + if (RD->isUnion()) { + // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the + // object's first non-static named data member is zero-initialized + // FIXME + return false; + } + + if (const auto *CXXRD = dyn_cast(RD); + CXXRD && CXXRD->getNumVBases() > 0) { + // TODO: Diagnose. + return false; + } + + const Record *R = getRecord(QT); + if (!R) + return false; + + assert(Initializing); + return this->visitZeroRecordInitializer(R, E); + } if (QT->isIncompleteArrayType()) return true; @@ -981,122 +1030,98 @@ bool ByteCodeExprGen::VisitArraySubscriptExpr( template bool ByteCodeExprGen::visitInitList(ArrayRef Inits, + const Expr *ArrayFiller, const Expr *E) { - assert(E->getType()->isRecordType()); - const Record *R = getRecord(E->getType()); + if (E->getType()->isVoidType()) + return this->emitInvalid(E); - if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) { - return this->visitInitializer(Inits[0]); + // Handle discarding first. + if (DiscardResult) { + for (const Expr *Init : Inits) { + if (!this->discard(Init)) + return false; + } + return true; } - unsigned InitIndex = 0; - for (const Expr *Init : Inits) { - // Skip unnamed bitfields. - while (InitIndex < R->getNumFields() && - R->getField(InitIndex)->Decl->isUnnamedBitField()) - ++InitIndex; + // Primitive values. + if (std::optional T = classify(E->getType())) { + assert(!DiscardResult); + if (Inits.size() == 0) + return this->visitZeroInitializer(*T, E->getType(), E); + assert(Inits.size() == 1); + return this->delegate(Inits[0]); + } - if (!this->emitDupPtr(E)) - return false; + QualType T = E->getType(); + if (T->isRecordType()) { + const Record *R = getRecord(E->getType()); - if (std::optional T = classify(Init)) { - const Record::Field *FieldToInit = R->getField(InitIndex); - if (!this->visit(Init)) - return false; + if (Inits.size() == 1 && E->getType() == Inits[0]->getType()) { + return this->visitInitializer(Inits[0]); + } - if (FieldToInit->isBitField()) { - if (!this->emitInitBitField(*T, FieldToInit, E)) - return false; - } else { - if (!this->emitInitField(*T, FieldToInit->Offset, E)) - return false; - } + unsigned InitIndex = 0; + for (const Expr *Init : Inits) { + // Skip unnamed bitfields. + while (InitIndex < R->getNumFields() && + R->getField(InitIndex)->Decl->isUnnamedBitField()) + ++InitIndex; - if (!this->emitPopPtr(E)) + if (!this->emitDupPtr(E)) return false; - ++InitIndex; - } else { - // Initializer for a direct base class. - if (const Record::Base *B = R->getBase(Init->getType())) { - if (!this->emitGetPtrBasePop(B->Offset, Init)) - return false; - if (!this->visitInitializer(Init)) - return false; - - if (!this->emitFinishInitPop(E)) - return false; - // Base initializers don't increase InitIndex, since they don't count - // into the Record's fields. - } else { + if (std::optional T = classify(Init)) { const Record::Field *FieldToInit = R->getField(InitIndex); - // Non-primitive case. Get a pointer to the field-to-initialize - // on the stack and recurse into visitInitializer(). - if (!this->emitGetPtrField(FieldToInit->Offset, Init)) + if (!this->visit(Init)) return false; - if (!this->visitInitializer(Init)) - return false; + if (FieldToInit->isBitField()) { + if (!this->emitInitBitField(*T, FieldToInit, E)) + return false; + } else { + if (!this->emitInitField(*T, FieldToInit->Offset, E)) + return false; + } if (!this->emitPopPtr(E)) return false; ++InitIndex; - } - } - } - return true; -} + } else { + // Initializer for a direct base class. + if (const Record::Base *B = R->getBase(Init->getType())) { + if (!this->emitGetPtrBasePop(B->Offset, Init)) + return false; -/// Pointer to the array(not the element!) must be on the stack when calling -/// this. -template -bool ByteCodeExprGen::visitArrayElemInit(unsigned ElemIndex, - const Expr *Init) { - if (std::optional T = classify(Init->getType())) { - // Visit the primitive element like normal. - if (!this->visit(Init)) - return false; - return this->emitInitElem(*T, ElemIndex, Init); - } + if (!this->visitInitializer(Init)) + return false; - // Advance the pointer currently on the stack to the given - // dimension. - if (!this->emitConstUint32(ElemIndex, Init)) - return false; - if (!this->emitArrayElemPtrUint32(Init)) - return false; - if (!this->visitInitializer(Init)) - return false; - return this->emitFinishInitPop(Init); -} + if (!this->emitFinishInitPop(E)) + return false; + // Base initializers don't increase InitIndex, since they don't count + // into the Record's fields. + } else { + const Record::Field *FieldToInit = R->getField(InitIndex); + // Non-primitive case. Get a pointer to the field-to-initialize + // on the stack and recurse into visitInitializer(). + if (!this->emitGetPtrField(FieldToInit->Offset, Init)) + return false; -template -bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { - // Handle discarding first. - if (DiscardResult) { - for (const Expr *Init : E->inits()) { - if (!this->discard(Init)) - return false; + if (!this->visitInitializer(Init)) + return false; + + if (!this->emitPopPtr(E)) + return false; + ++InitIndex; + } + } } return true; } - // Primitive values. - if (std::optional T = classify(E->getType())) { - assert(!DiscardResult); - if (E->getNumInits() == 0) - return this->visitZeroInitializer(*T, E->getType(), E); - assert(E->getNumInits() == 1); - return this->delegate(E->inits()[0]); - } - - QualType T = E->getType(); - if (T->isRecordType()) - return this->visitInitList(E->inits(), E); - if (T->isArrayType()) { unsigned ElementIndex = 0; - for (const Expr *Init : E->inits()) { + for (const Expr *Init : Inits) { if (!this->visitArrayElemInit(ElementIndex, Init)) return false; ++ElementIndex; @@ -1104,13 +1129,13 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { // Expand the filler expression. // FIXME: This should go away. - if (const Expr *Filler = E->getArrayFiller()) { + if (ArrayFiller) { const ConstantArrayType *CAT = Ctx.getASTContext().getAsConstantArrayType(E->getType()); uint64_t NumElems = CAT->getZExtSize(); for (; ElementIndex != NumElems; ++ElementIndex) { - if (!this->visitArrayElemInit(ElementIndex, Filler)) + if (!this->visitArrayElemInit(ElementIndex, ArrayFiller)) return false; } } @@ -1119,10 +1144,10 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { } if (const auto *ComplexTy = E->getType()->getAs()) { - unsigned NumInits = E->getNumInits(); + unsigned NumInits = Inits.size(); if (NumInits == 1) - return this->delegate(E->inits()[0]); + return this->delegate(Inits[0]); QualType ElemQT = ComplexTy->getElementType(); PrimType ElemT = classifyPrim(ElemQT); @@ -1136,7 +1161,7 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { } } else if (NumInits == 2) { unsigned InitIndex = 0; - for (const Expr *Init : E->inits()) { + for (const Expr *Init : Inits) { if (!this->visit(Init)) return false; @@ -1150,14 +1175,14 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { if (const auto *VecT = E->getType()->getAs()) { unsigned NumVecElements = VecT->getNumElements(); - assert(NumVecElements >= E->getNumInits()); + assert(NumVecElements >= Inits.size()); QualType ElemQT = VecT->getElementType(); PrimType ElemT = classifyPrim(ElemQT); // All initializer elements. unsigned InitIndex = 0; - for (const Expr *Init : E->inits()) { + for (const Expr *Init : Inits) { if (!this->visit(Init)) return false; @@ -1179,19 +1204,38 @@ bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { return false; } +/// Pointer to the array(not the element!) must be on the stack when calling +/// this. template -bool ByteCodeExprGen::VisitCXXParenListInitExpr( - const CXXParenListInitExpr *E) { - if (DiscardResult) { - for (const Expr *Init : E->getInitExprs()) { - if (!this->discard(Init)) - return false; - } - return true; +bool ByteCodeExprGen::visitArrayElemInit(unsigned ElemIndex, + const Expr *Init) { + if (std::optional T = classify(Init->getType())) { + // Visit the primitive element like normal. + if (!this->visit(Init)) + return false; + return this->emitInitElem(*T, ElemIndex, Init); } - assert(E->getType()->isRecordType()); - return this->visitInitList(E->getInitExprs(), E); + // Advance the pointer currently on the stack to the given + // dimension. + if (!this->emitConstUint32(ElemIndex, Init)) + return false; + if (!this->emitArrayElemPtrUint32(Init)) + return false; + if (!this->visitInitializer(Init)) + return false; + return this->emitFinishInitPop(Init); +} + +template +bool ByteCodeExprGen::VisitInitListExpr(const InitListExpr *E) { + return this->visitInitList(E->inits(), E->getArrayFiller(), E); +} + +template +bool ByteCodeExprGen::VisitCXXParenListInitExpr( + const CXXParenListInitExpr *E) { + return this->visitInitList(E->getInitExprs(), E->getArrayFiller(), E); } template @@ -1314,6 +1358,20 @@ bool ByteCodeExprGen::VisitUnaryExprOrTypeTraitExpr( assert(E->getTypeOfArgument()->isSizelessVectorType()); } + if (Kind == UETT_VecStep) { + if (const auto *VT = E->getTypeOfArgument()->getAs()) { + unsigned N = VT->getNumElements(); + + // The vec_step built-in functions that take a 3-component + // vector return 4. (OpenCL 1.1 spec 6.11.12) + if (N == 3) + N = 4; + + return this->emitConst(N, E); + } + return this->emitConst(1, E); + } + return false; } @@ -2321,8 +2379,7 @@ bool ByteCodeExprGen::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { if (!this->emitGetPtrGlobal(*GlobalIndex, E)) return false; - const Record *R = this->getRecord(E->getType()); - assert(R); + assert(this->getRecord(E->getType())); const APValue &V = E->getGuidDecl()->getAsAPValue(); if (V.getKind() == APValue::None) @@ -2330,41 +2387,8 @@ bool ByteCodeExprGen::VisitCXXUuidofExpr(const CXXUuidofExpr *E) { assert(V.isStruct()); assert(V.getStructNumBases() == 0); - // FIXME: This could be useful in visitAPValue, too. - for (unsigned I = 0, N = V.getStructNumFields(); I != N; ++I) { - const APValue &F = V.getStructField(I); - const Record::Field *RF = R->getField(I); - - if (F.isInt()) { - PrimType T = classifyPrim(RF->Decl->getType()); - if (!this->visitAPValue(F, T, E)) - return false; - if (!this->emitInitField(T, RF->Offset, E)) - return false; - } else if (F.isArray()) { - assert(RF->Desc->isPrimitiveArray()); - const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe(); - PrimType ElemT = classifyPrim(ArrType->getElementType()); - assert(ArrType); - - if (!this->emitDupPtr(E)) - return false; - if (!this->emitGetPtrField(RF->Offset, E)) - return false; - - for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) { - if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E)) - return false; - if (!this->emitInitElem(ElemT, A, E)) - return false; - } - - if (!this->emitPopPtr(E)) - return false; - } else { - assert(false && "I don't think this should be possible"); - } - } + if (!this->visitAPValueInitializer(V, E)) + return false; return this->emitFinishInit(E); } @@ -2929,6 +2953,54 @@ bool ByteCodeExprGen::visitAPValue(const APValue &Val, return false; } +template +bool ByteCodeExprGen::visitAPValueInitializer(const APValue &Val, + const Expr *E) { + if (Val.isStruct()) { + const Record *R = this->getRecord(E->getType()); + assert(R); + + for (unsigned I = 0, N = Val.getStructNumFields(); I != N; ++I) { + const APValue &F = Val.getStructField(I); + const Record::Field *RF = R->getField(I); + + if (F.isInt()) { + PrimType T = classifyPrim(RF->Decl->getType()); + if (!this->visitAPValue(F, T, E)) + return false; + if (!this->emitInitField(T, RF->Offset, E)) + return false; + } else if (F.isArray()) { + assert(RF->Desc->isPrimitiveArray()); + const auto *ArrType = RF->Decl->getType()->getAsArrayTypeUnsafe(); + PrimType ElemT = classifyPrim(ArrType->getElementType()); + assert(ArrType); + + if (!this->emitDupPtr(E)) + return false; + if (!this->emitGetPtrField(RF->Offset, E)) + return false; + + for (unsigned A = 0, AN = F.getArraySize(); A != AN; ++A) { + if (!this->visitAPValue(F.getArrayInitializedElt(A), ElemT, E)) + return false; + if (!this->emitInitElem(ElemT, A, E)) + return false; + } + + if (!this->emitPopPtr(E)) + return false; + } else { + assert(false && "I don't think this should be possible"); + } + } + return true; + } + // TODO: Other types. + + return false; +} + template bool ByteCodeExprGen::VisitBuiltinCallExpr(const CallExpr *E) { const Function *Func = getFunction(E->getDirectCallee()); @@ -3450,9 +3522,17 @@ bool ByteCodeExprGen::VisitDeclRefExpr(const DeclRefExpr *E) { } else if (const auto *FuncDecl = dyn_cast(D)) { const Function *F = getFunction(FuncDecl); return F && this->emitGetFnPtr(F, E); - } else if (isa(D)) { - if (std::optional Index = P.getOrCreateGlobal(D)) - return this->emitGetPtrGlobal(*Index, E); + } else if (const auto *TPOD = dyn_cast(D)) { + if (std::optional Index = P.getOrCreateGlobal(D)) { + if (!this->emitGetPtrGlobal(*Index, E)) + return false; + if (std::optional T = classify(E->getType())) { + if (!this->visitAPValue(TPOD->getValue(), *T, E)) + return false; + return this->emitInitGlobal(*T, *Index, E); + } + return this->visitAPValueInitializer(TPOD->getValue(), E); + } return false; } @@ -3529,35 +3609,17 @@ void ByteCodeExprGen::emitCleanup() { template unsigned -ByteCodeExprGen::collectBaseOffset(const RecordType *BaseType, - const RecordType *DerivedType) { - assert(BaseType); - assert(DerivedType); - const auto *FinalDecl = cast(BaseType->getDecl()); - const RecordDecl *CurDecl = DerivedType->getDecl(); - const Record *CurRecord = getRecord(CurDecl); - assert(CurDecl && FinalDecl); - - unsigned OffsetSum = 0; - for (;;) { - assert(CurRecord->getNumBases() > 0); - // One level up - for (const Record::Base &B : CurRecord->bases()) { - const auto *BaseDecl = cast(B.Decl); - - if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) { - OffsetSum += B.Offset; - CurRecord = B.R; - CurDecl = BaseDecl; - break; - } - } - if (CurDecl == FinalDecl) - break; - } +ByteCodeExprGen::collectBaseOffset(const QualType BaseType, + const QualType DerivedType) { + const auto extractRecordDecl = [](QualType Ty) -> const CXXRecordDecl * { + if (const auto *PT = dyn_cast(Ty)) + return PT->getPointeeType()->getAsCXXRecordDecl(); + return Ty->getAsCXXRecordDecl(); + }; + const CXXRecordDecl *BaseDecl = extractRecordDecl(BaseType); + const CXXRecordDecl *DerivedDecl = extractRecordDecl(DerivedType); - assert(OffsetSum > 0); - return OffsetSum; + return Ctx.collectBaseOffset(BaseDecl, DerivedDecl); } /// Emit casts from a PrimType to another PrimType. diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h index 7e9dc8631fc0..a89e37c67aa6 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.h +++ b/clang/lib/AST/Interp/ByteCodeExprGen.h @@ -181,6 +181,7 @@ protected: bool visitVarDecl(const VarDecl *VD); /// Visit an APValue. bool visitAPValue(const APValue &Val, PrimType ValType, const Expr *E); + bool visitAPValueInitializer(const APValue &Val, const Expr *E); /// Visits an expression and converts it to a boolean. bool visitBool(const Expr *E); @@ -224,7 +225,8 @@ protected: return this->emitFinishInitPop(I); } - bool visitInitList(ArrayRef Inits, const Expr *E); + bool visitInitList(ArrayRef Inits, const Expr *ArrayFiller, + const Expr *E); bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init); /// Creates a local primitive value. @@ -283,8 +285,8 @@ private: bool emitRecordDestruction(const Record *R); bool emitDestruction(const Descriptor *Desc); - unsigned collectBaseOffset(const RecordType *BaseType, - const RecordType *DerivedType); + unsigned collectBaseOffset(const QualType BaseType, + const QualType DerivedType); protected: /// Variable to storage mapping. diff --git a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp index 36dab6252ece..ff91baf595f1 100644 --- a/clang/lib/AST/Interp/ByteCodeStmtGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeStmtGen.cpp @@ -189,14 +189,23 @@ bool ByteCodeStmtGen::visitFunc(const FunctionDecl *F) { if (!emitFieldInitializer(F, F->Offset, InitExpr)) return false; } else if (const Type *Base = Init->getBaseClass()) { - // Base class initializer. - // Get This Base and call initializer on it. const auto *BaseDecl = Base->getAsCXXRecordDecl(); assert(BaseDecl); - const Record::Base *B = R->getBase(BaseDecl); - assert(B); - if (!this->emitGetPtrThisBase(B->Offset, InitExpr)) - return false; + + if (Init->isBaseVirtual()) { + assert(R->getVirtualBase(BaseDecl)); + if (!this->emitGetPtrThisVirtBase(BaseDecl, InitExpr)) + return false; + + } else { + // Base class initializer. + // Get This Base and call initializer on it. + const Record::Base *B = R->getBase(BaseDecl); + assert(B); + if (!this->emitGetPtrThisBase(B->Offset, InitExpr)) + return false; + } + if (!this->visitInitializer(InitExpr)) return false; if (!this->emitFinishInitPop(InitExpr)) @@ -323,7 +332,8 @@ bool ByteCodeStmtGen::visitCompoundStmt( template bool ByteCodeStmtGen::visitDeclStmt(const DeclStmt *DS) { for (auto *D : DS->decls()) { - if (isa(D)) + if (isa(D)) continue; const auto *VD = dyn_cast(D); diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 274178837bf0..d51a57e5e92e 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -262,3 +262,36 @@ const Function *Context::getOrCreateFunction(const FunctionDecl *FD) { return Func; } + +unsigned Context::collectBaseOffset(const RecordDecl *BaseDecl, + const RecordDecl *DerivedDecl) const { + assert(BaseDecl); + assert(DerivedDecl); + const auto *FinalDecl = cast(BaseDecl); + const RecordDecl *CurDecl = DerivedDecl; + const Record *CurRecord = P->getOrCreateRecord(CurDecl); + assert(CurDecl && FinalDecl); + + unsigned OffsetSum = 0; + for (;;) { + assert(CurRecord->getNumBases() > 0); + // One level up + for (const Record::Base &B : CurRecord->bases()) { + const auto *BaseDecl = cast(B.Decl); + + if (BaseDecl == FinalDecl || BaseDecl->isDerivedFrom(FinalDecl)) { + OffsetSum += B.Offset; + CurRecord = B.R; + CurDecl = BaseDecl; + break; + } + } + if (CurDecl == FinalDecl) + break; + + // break; + } + + assert(OffsetSum > 0); + return OffsetSum; +} diff --git a/clang/lib/AST/Interp/Context.h b/clang/lib/AST/Interp/Context.h index 23c439ad8912..360e9499d084 100644 --- a/clang/lib/AST/Interp/Context.h +++ b/clang/lib/AST/Interp/Context.h @@ -104,6 +104,9 @@ public: /// Returns the program. This is only needed for unittests. Program &getProgram() const { return *P.get(); } + unsigned collectBaseOffset(const RecordDecl *BaseDecl, + const RecordDecl *DerivedDecl) const; + private: /// Runs a function. bool Run(State &Parent, const Function *Func, APValue &Result); diff --git a/clang/lib/AST/Interp/Descriptor.cpp b/clang/lib/AST/Interp/Descriptor.cpp index a4ccc0236d29..954c58c8cb37 100644 --- a/clang/lib/AST/Interp/Descriptor.cpp +++ b/clang/lib/AST/Interp/Descriptor.cpp @@ -136,28 +136,66 @@ static void moveArrayDesc(Block *B, const std::byte *Src, std::byte *Dst, } } +static void initField(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, + bool IsActive, const Descriptor *D, + unsigned FieldOffset) { + bool IsUnion = false; // FIXME + auto *Desc = reinterpret_cast(Ptr + FieldOffset) - 1; + Desc->Offset = FieldOffset; + Desc->Desc = D; + Desc->IsInitialized = D->IsArray; + Desc->IsBase = false; + Desc->IsActive = IsActive && !IsUnion; + Desc->IsConst = IsConst || D->IsConst; + Desc->IsFieldMutable = IsMutable || D->IsMutable; + + if (auto Fn = D->CtorFn) + Fn(B, Ptr + FieldOffset, Desc->IsConst, Desc->IsFieldMutable, + Desc->IsActive, D); +} + +static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, + bool IsActive, const Descriptor *D, unsigned FieldOffset, + bool IsVirtualBase) { + assert(D); + assert(D->ElemRecord); + + bool IsUnion = D->ElemRecord->isUnion(); + auto *Desc = reinterpret_cast(Ptr + FieldOffset) - 1; + Desc->Offset = FieldOffset; + Desc->Desc = D; + Desc->IsInitialized = D->IsArray; + Desc->IsBase = true; + Desc->IsActive = IsActive && !IsUnion; + Desc->IsConst = IsConst || D->IsConst; + Desc->IsFieldMutable = IsMutable || D->IsMutable; + + for (const auto &V : D->ElemRecord->bases()) + initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc, + V.Offset, false); + for (const auto &F : D->ElemRecord->fields()) + initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, F.Desc, + F.Offset); + + // If this is initializing a virtual base, we do NOT want to consider its + // virtual bases, those are already flattened into the parent record when + // creating it. + if (IsVirtualBase) + return; + + for (const auto &V : D->ElemRecord->virtual_bases()) + initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsActive, V.Desc, + V.Offset, true); +} + static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable, bool IsActive, const Descriptor *D) { - const bool IsUnion = D->ElemRecord->isUnion(); - auto CtorSub = [=](unsigned SubOff, const Descriptor *F, bool IsBase) { - auto *Desc = reinterpret_cast(Ptr + SubOff) - 1; - Desc->Offset = SubOff; - Desc->Desc = F; - Desc->IsInitialized = F->IsArray && !IsBase; - Desc->IsBase = IsBase; - Desc->IsActive = IsActive && !IsUnion; - Desc->IsConst = IsConst || F->IsConst; - Desc->IsFieldMutable = IsMutable || F->IsMutable; - if (auto Fn = F->CtorFn) - Fn(B, Ptr + SubOff, Desc->IsConst, Desc->IsFieldMutable, Desc->IsActive, - F); - }; - for (const auto &B : D->ElemRecord->bases()) - CtorSub(B.Offset, B.Desc, /*isBase=*/true); + for (const auto &V : D->ElemRecord->bases()) + initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, false); for (const auto &F : D->ElemRecord->fields()) - CtorSub(F.Offset, F.Desc, /*isBase=*/false); + initField(B, Ptr, IsConst, IsMutable, IsActive, F.Desc, F.Offset); for (const auto &V : D->ElemRecord->virtual_bases()) - CtorSub(V.Offset, V.Desc, /*isBase=*/true); + initBase(B, Ptr, IsConst, IsMutable, IsActive, V.Desc, V.Offset, true); } static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) { diff --git a/clang/lib/AST/Interp/Descriptor.h b/clang/lib/AST/Interp/Descriptor.h index c386fc8ac7b0..cd20495c259c 100644 --- a/clang/lib/AST/Interp/Descriptor.h +++ b/clang/lib/AST/Interp/Descriptor.h @@ -82,6 +82,9 @@ struct InlineDescriptor { InlineDescriptor(const Descriptor *D) : Offset(sizeof(InlineDescriptor)), IsConst(false), IsInitialized(false), IsBase(false), IsActive(false), IsFieldMutable(false), Desc(D) {} + + void dump() const { dump(llvm::errs()); } + void dump(llvm::raw_ostream &OS) const; }; /// Describes a memory block created by an allocation site. diff --git a/clang/lib/AST/Interp/Disasm.cpp b/clang/lib/AST/Interp/Disasm.cpp index d127f33223e8..ccdc96a79436 100644 --- a/clang/lib/AST/Interp/Disasm.cpp +++ b/clang/lib/AST/Interp/Disasm.cpp @@ -200,7 +200,7 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { OS << " primitive"; if (isZeroSizeArray()) - OS << " zero-size-arrary"; + OS << " zero-size-array"; else if (isUnknownSizeArray()) OS << " unknown-size-array"; @@ -208,6 +208,25 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const { OS << " dummy"; } +LLVM_DUMP_METHOD void InlineDescriptor::dump(llvm::raw_ostream &OS) const { + { + ColorScope SC(OS, true, {llvm::raw_ostream::BLUE, true}); + OS << "InlineDescriptor " << (const void *)this << "\n"; + } + OS << "Offset: " << Offset << "\n"; + OS << "IsConst: " << IsConst << "\n"; + OS << "IsInitialized: " << IsInitialized << "\n"; + OS << "IsBase: " << IsBase << "\n"; + OS << "IsActive: " << IsActive << "\n"; + OS << "IsFieldMutable: " << IsFieldMutable << "\n"; + OS << "Desc: "; + if (Desc) + Desc->dump(OS); + else + OS << "nullptr"; + OS << "\n"; +} + LLVM_DUMP_METHOD void InterpFrame::dump(llvm::raw_ostream &OS, unsigned Indent) const { unsigned Spaces = Indent * 2; @@ -251,8 +270,6 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation, ++I; } - // FIXME: Virtual bases. - I = 0; for (const Record::Field &F : fields()) { OS.indent(Indent) << "- Field " << I << ": "; @@ -263,6 +280,14 @@ LLVM_DUMP_METHOD void Record::dump(llvm::raw_ostream &OS, unsigned Indentation, OS << ". Offset " << (Offset + F.Offset) << "\n"; ++I; } + + I = 0; + for (const Record::Base &B : virtual_bases()) { + OS.indent(Indent) << "- Virtual Base " << I << ". Offset " + << (Offset + B.Offset) << "\n"; + B.R->dump(OS, Indentation + 1, Offset + B.Offset); + ++I; + } } LLVM_DUMP_METHOD void Block::dump(llvm::raw_ostream &OS) const { diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 9283f697c007..9da0286deada 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1355,20 +1355,26 @@ inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, const RecordDecl *Decl, while (Base.isBaseClass()) Base = Base.getBase(); - auto *Field = Base.getRecord()->getVirtualBase(Decl); - S.Stk.push(Base.atField(Field->Offset)); + const Record::Base *VirtBase = Base.getRecord()->getVirtualBase(Decl); + S.Stk.push(Base.atField(VirtBase->Offset)); return true; } -inline bool GetPtrVirtBase(InterpState &S, CodePtr OpPC, const RecordDecl *D) { +inline bool GetPtrVirtBasePop(InterpState &S, CodePtr OpPC, + const RecordDecl *D) { + assert(D); const Pointer &Ptr = S.Stk.pop(); if (!CheckNull(S, OpPC, Ptr, CSK_Base)) return false; + if (Ptr.isDummy()) // FIXME: Once we have type info for dummy pointers, this + // needs to go. + return false; return VirtBaseHelper(S, OpPC, D, Ptr); } inline bool GetPtrThisVirtBase(InterpState &S, CodePtr OpPC, const RecordDecl *D) { + assert(D); if (S.checkingPotentialConstantExpression()) return false; const Pointer &This = S.Current->getThis(); diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 742785b28eb4..2a97b978b523 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -336,7 +336,7 @@ def GetPtrDerivedPop : Opcode { } // [Pointer] -> [Pointer] -def GetPtrVirtBase : Opcode { +def GetPtrVirtBasePop : Opcode { // RecordDecl of base class. let Args = [ArgRecordDecl]; } diff --git a/clang/lib/AST/Interp/Program.cpp b/clang/lib/AST/Interp/Program.cpp index 3773e0662f78..02075c20cf55 100644 --- a/clang/lib/AST/Interp/Program.cpp +++ b/clang/lib/AST/Interp/Program.cpp @@ -173,7 +173,8 @@ std::optional Program::createGlobal(const ValueDecl *VD, if (const auto *Var = dyn_cast(VD)) { IsStatic = Context::shouldBeGloballyIndexed(VD); IsExtern = Var->hasExternalStorage(); - } else if (isa(VD)) { + } else if (isa(VD)) { IsStatic = true; IsExtern = false; } else { diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 106c69dd5bee..ed9e6eeb36c7 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4715,7 +4715,7 @@ recurse: case Expr::MSPropertySubscriptExprClass: case Expr::TypoExprClass: // This should no longer exist in the AST by now. case Expr::RecoveryExprClass: - case Expr::OMPArraySectionExprClass: + case Expr::ArraySectionExprClass: case Expr::OMPArrayShapingExprClass: case Expr::OMPIteratorExprClass: case Expr::CXXInheritedCtorInitExprClass: diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index ecc56c13fb75..6f586173edb0 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -462,7 +462,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::PseudoObject: case BuiltinType::BuiltinFn: case BuiltinType::IncompleteMatrixIdx: - case BuiltinType::OMPArraySection: + case BuiltinType::ArraySection: case BuiltinType::OMPArrayShaping: case BuiltinType::OMPIterator: case BuiltinType::BFloat16: diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 5855ab3141ed..f010d36513a4 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1521,7 +1521,7 @@ void StmtPrinter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *Node) { OS << "]"; } -void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { +void StmtPrinter::VisitArraySectionExpr(ArraySectionExpr *Node) { PrintExpr(Node->getBase()); OS << "["; if (Node->getLowerBound()) @@ -1531,7 +1531,7 @@ void StmtPrinter::VisitOMPArraySectionExpr(OMPArraySectionExpr *Node) { if (Node->getLength()) PrintExpr(Node->getLength()); } - if (Node->getColonLocSecond().isValid()) { + if (Node->isOMPArraySection() && Node->getColonLocSecond().isValid()) { OS << ":"; if (Node->getStride()) PrintExpr(Node->getStride()); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index c81724f84dd9..a95f5c6103e2 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1435,7 +1435,7 @@ void StmtProfiler::VisitMatrixSubscriptExpr(const MatrixSubscriptExpr *S) { VisitExpr(S); } -void StmtProfiler::VisitOMPArraySectionExpr(const OMPArraySectionExpr *S) { +void StmtProfiler::VisitArraySectionExpr(const ArraySectionExpr *S) { VisitExpr(S); } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index cb22c91a12aa..68e81f45b4c2 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2510,6 +2510,18 @@ bool Type::isSveVLSBuiltinType() const { return false; } +QualType Type::getSizelessVectorEltType(const ASTContext &Ctx) const { + assert(isSizelessVectorType() && "Must be sizeless vector type"); + // Currently supports SVE and RVV + if (isSVESizelessBuiltinType()) + return getSveEltType(Ctx); + + if (isRVVSizelessBuiltinType()) + return getRVVEltType(Ctx); + + llvm_unreachable("Unhandled type"); +} + QualType Type::getSveEltType(const ASTContext &Ctx) const { assert(isSveVLSBuiltinType() && "unsupported type!"); @@ -3413,8 +3425,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { return "reserve_id_t"; case IncompleteMatrixIdx: return ""; - case OMPArraySection: - return ""; + case ArraySection: + return ""; case OMPArrayShaping: return ""; case OMPIterator: @@ -4710,7 +4722,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::BuiltinFn: case BuiltinType::NullPtr: case BuiltinType::IncompleteMatrixIdx: - case BuiltinType::OMPArraySection: + case BuiltinType::ArraySection: case BuiltinType::OMPArrayShaping: case BuiltinType::OMPIterator: return false; diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 21e152f6aea8..ce45b47d5cfe 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -429,7 +429,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { #include "clang/Basic/WebAssemblyReferenceTypes.def" case BuiltinType::BuiltinFn: case BuiltinType::IncompleteMatrixIdx: - case BuiltinType::OMPArraySection: + case BuiltinType::ArraySection: case BuiltinType::OMPArrayShaping: case BuiltinType::OMPIterator: return TST_unspecified; diff --git a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp index 619bf772bba5..bd1676583ecc 100644 --- a/clang/lib/Analysis/FlowSensitive/ASTOps.cpp +++ b/clang/lib/Analysis/FlowSensitive/ASTOps.cpp @@ -33,12 +33,20 @@ namespace clang::dataflow { const Expr &ignoreCFGOmittedNodes(const Expr &E) { const Expr *Current = &E; - if (auto *EWC = dyn_cast(Current)) { - Current = EWC->getSubExpr(); + const Expr *Last = nullptr; + while (Current != Last) { + Last = Current; + if (auto *EWC = dyn_cast(Current)) { + Current = EWC->getSubExpr(); + assert(Current != nullptr); + } + if (auto *CE = dyn_cast(Current)) { + Current = CE->getSubExpr(); + assert(Current != nullptr); + } + Current = Current->IgnoreParens(); assert(Current != nullptr); } - Current = Current->IgnoreParens(); - assert(Current != nullptr); return *Current; } diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp index 05395e07a7a6..d79e73440289 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp @@ -157,7 +157,13 @@ static WidenResult widenDistinctValues(QualType Type, Value &Prev, Value &Current, Environment &CurrentEnv, Environment::ValueModel &Model) { // Boolean-model widening. - if (auto *PrevBool = dyn_cast(&Prev)) { + if (isa(Prev) && isa(Current)) { + // FIXME: Checking both values should be unnecessary, but we can currently + // end up with `BoolValue`s in integer-typed variables. See comment in + // `joinDistinctValues()` for details. + auto &PrevBool = cast(Prev); + auto &CurBool = cast(Current); + if (isa(Prev)) // Safe to return `Prev` here, because Top is never dependent on the // environment. @@ -166,13 +172,12 @@ static WidenResult widenDistinctValues(QualType Type, Value &Prev, // We may need to widen to Top, but before we do so, check whether both // values are implied to be either true or false in the current environment. // In that case, we can simply return a literal instead. - auto &CurBool = cast(Current); - bool TruePrev = PrevEnv.proves(PrevBool->formula()); + bool TruePrev = PrevEnv.proves(PrevBool.formula()); bool TrueCur = CurrentEnv.proves(CurBool.formula()); if (TruePrev && TrueCur) return {&CurrentEnv.getBoolLiteralValue(true), LatticeEffect::Unchanged}; if (!TruePrev && !TrueCur && - PrevEnv.proves(PrevEnv.arena().makeNot(PrevBool->formula())) && + PrevEnv.proves(PrevEnv.arena().makeNot(PrevBool.formula())) && CurrentEnv.proves(CurrentEnv.arena().makeNot(CurBool.formula()))) return {&CurrentEnv.getBoolLiteralValue(false), LatticeEffect::Unchanged}; @@ -237,13 +242,8 @@ joinLocToVal(const llvm::MapVector &LocToVal, continue; assert(It->second != nullptr); - if (areEquivalentValues(*Val, *It->second)) { - Result.insert({Loc, Val}); - continue; - } - - if (Value *JoinedVal = joinDistinctValues( - Loc->getType(), *Val, Env1, *It->second, Env2, JoinedEnv, Model)) { + if (Value *JoinedVal = Environment::joinValues( + Loc->getType(), Val, Env1, It->second, Env2, JoinedEnv, Model)) { Result.insert({Loc, JoinedVal}); } } @@ -338,6 +338,18 @@ public: } } + bool TraverseDecl(Decl *D) { + // Don't traverse nested record or function declarations. + // - We won't be analyzing code contained in these anyway + // - We don't model fields that are used only in these nested declaration, + // so trying to propagate a result object to initializers of such fields + // would cause an error. + if (isa_and_nonnull(D) || isa_and_nonnull(D)) + return true; + + return RecursiveASTVisitor::TraverseDecl(D); + } + bool TraverseBindingDecl(BindingDecl *BD) { // `RecursiveASTVisitor` doesn't traverse holding variables for // `BindingDecl`s by itself, so we need to tell it to. @@ -775,27 +787,16 @@ Environment Environment::join(const Environment &EnvA, const Environment &EnvB, JoinedEnv.LocForRecordReturnVal = EnvA.LocForRecordReturnVal; JoinedEnv.ThisPointeeLoc = EnvA.ThisPointeeLoc; - if (EnvA.ReturnVal == nullptr || EnvB.ReturnVal == nullptr) { - // `ReturnVal` might not always get set -- for example if we have a return - // statement of the form `return some_other_func()` and we decide not to - // analyze `some_other_func()`. - // In this case, we can't say anything about the joined return value -- we - // don't simply want to propagate the return value that we do have, because - // it might not be the correct one. - // This occurs for example in the test `ContextSensitiveMutualRecursion`. + if (EnvA.CallStack.empty()) { JoinedEnv.ReturnVal = nullptr; - } else if (areEquivalentValues(*EnvA.ReturnVal, *EnvB.ReturnVal)) { - JoinedEnv.ReturnVal = EnvA.ReturnVal; } else { - assert(!EnvA.CallStack.empty()); // FIXME: Make `CallStack` a vector of `FunctionDecl` so we don't need this // cast. auto *Func = dyn_cast(EnvA.CallStack.back()); assert(Func != nullptr); - if (Value *JoinedVal = - joinDistinctValues(Func->getReturnType(), *EnvA.ReturnVal, EnvA, - *EnvB.ReturnVal, EnvB, JoinedEnv, Model)) - JoinedEnv.ReturnVal = JoinedVal; + JoinedEnv.ReturnVal = + joinValues(Func->getReturnType(), EnvA.ReturnVal, EnvA, EnvB.ReturnVal, + EnvB, JoinedEnv, Model); } if (EnvA.ReturnLoc == EnvB.ReturnLoc) @@ -821,6 +822,24 @@ Environment Environment::join(const Environment &EnvA, const Environment &EnvB, return JoinedEnv; } +Value *Environment::joinValues(QualType Ty, Value *Val1, + const Environment &Env1, Value *Val2, + const Environment &Env2, Environment &JoinedEnv, + Environment::ValueModel &Model) { + if (Val1 == nullptr || Val2 == nullptr) + // We can't say anything about the joined value -- even if one of the values + // is non-null, we don't want to simply propagate it, because it would be + // too specific: Because the other value is null, that means we have no + // information at all about the value (i.e. the value is unconstrained). + return nullptr; + + if (areEquivalentValues(*Val1, *Val2)) + // Arbitrarily return one of the two values. + return Val1; + + return joinDistinctValues(Ty, *Val1, Env1, *Val2, Env2, JoinedEnv, Model); +} + StorageLocation &Environment::createStorageLocation(QualType Type) { return DACtx->createStorageLocation(Type); } diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp index 2771c8b2e37e..fd224aeb79b1 100644 --- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp +++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp @@ -41,7 +41,11 @@ namespace dataflow { const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const { auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S)); - assert(BlockIt != ACFG.getStmtToBlock().end()); + if (BlockIt == ACFG.getStmtToBlock().end()) { + assert(false); + // Return null to avoid dereferencing the end iterator in non-assert builds. + return nullptr; + } if (!ACFG.isBlockReachable(*BlockIt->getSecond())) return nullptr; if (BlockIt->getSecond()->getBlockID() == CurBlockID) @@ -124,8 +128,9 @@ namespace { class TransferVisitor : public ConstStmtVisitor { public: - TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env) - : StmtToEnv(StmtToEnv), Env(Env) {} + TransferVisitor(const StmtToEnvMap &StmtToEnv, Environment &Env, + Environment::ValueModel &Model) + : StmtToEnv(StmtToEnv), Env(Env), Model(Model) {} void VisitBinaryOperator(const BinaryOperator *S) { const Expr *LHS = S->getLHS(); @@ -641,17 +646,42 @@ public: } void VisitConditionalOperator(const ConditionalOperator *S) { - // FIXME: Revisit this once flow conditions are added to the framework. For - // `a = b ? c : d` we can add `b => a == c && !b => a == d` to the flow - // condition. - // When we do this, we will need to retrieve the values of the operands from - // the environments for the basic blocks they are computed in, in a similar - // way to how this is done for short-circuited logical operators in - // `getLogicOperatorSubExprValue()`. - if (S->isGLValue()) - Env.setStorageLocation(*S, Env.createObject(S->getType())); - else if (!S->getType()->isRecordType()) { - if (Value *Val = Env.createValue(S->getType())) + const Environment *TrueEnv = StmtToEnv.getEnvironment(*S->getTrueExpr()); + const Environment *FalseEnv = StmtToEnv.getEnvironment(*S->getFalseExpr()); + + if (TrueEnv == nullptr || FalseEnv == nullptr) { + // If the true or false branch is dead, we may not have an environment for + // it. We could handle this specifically by forwarding the value or + // location of the live branch, but this case is rare enough that this + // probably isn't worth the additional complexity. + return; + } + + if (S->isGLValue()) { + StorageLocation *TrueLoc = TrueEnv->getStorageLocation(*S->getTrueExpr()); + StorageLocation *FalseLoc = + FalseEnv->getStorageLocation(*S->getFalseExpr()); + if (TrueLoc == FalseLoc && TrueLoc != nullptr) + Env.setStorageLocation(*S, *TrueLoc); + } else if (!S->getType()->isRecordType()) { + // The conditional operator can evaluate to either of the values of the + // two branches. To model this, join these two values together to yield + // the result of the conditional operator. + // Note: Most joins happen in `computeBlockInputState()`, but this case is + // different: + // - `computeBlockInputState()` (which in turn calls `Environment::join()` + // joins values associated with the _same_ expression or storage + // location, then associates the joined value with that expression or + // storage location. This join has nothing to do with transfer -- + // instead, it joins together the results of performing transfer on two + // different blocks. + // - Here, we join values associated with _different_ expressions (the + // true and false branch), then associate the joined value with a third + // expression (the conditional operator itself). This join is what it + // means to perform transfer on the conditional operator. + if (Value *Val = Environment::joinValues( + S->getType(), TrueEnv->getValue(*S->getTrueExpr()), *TrueEnv, + FalseEnv->getValue(*S->getFalseExpr()), *FalseEnv, Env, Model)) Env.setValue(*S, *Val); } } @@ -810,12 +840,14 @@ private: const StmtToEnvMap &StmtToEnv; Environment &Env; + Environment::ValueModel &Model; }; } // namespace -void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env) { - TransferVisitor(StmtToEnv, Env).Visit(&S); +void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env, + Environment::ValueModel &Model) { + TransferVisitor(StmtToEnv, Env, Model).Visit(&S); } } // namespace dataflow diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 71d5c1a6c4f4..12eff4dd4b78 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -316,7 +316,7 @@ builtinTransferStatement(unsigned CurBlockID, const CFGStmt &Elt, const Stmt *S = Elt.getStmt(); assert(S != nullptr); transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, CurBlockID, InputState), *S, - InputState.Env); + InputState.Env, AC.Analysis); } /// Built-in transfer function for `CFGInitializer`. @@ -452,7 +452,7 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC, // terminator condition, but not as a `CFGElement`. The condition of an if // statement is one such example. transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, Block.getBlockID(), State), - *TerminatorCond, State.Env); + *TerminatorCond, State.Env, AC.Analysis); // If the transfer function didn't produce a value, create an atom so that // we have *some* value for the condition expression. This ensures that diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index cd520a6375e0..143c04309d07 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -39,12 +39,6 @@ using namespace clang; #define DEBUG_TYPE "file-search" -ALWAYS_ENABLED_STATISTIC(NumDirLookups, "Number of directory lookups."); -ALWAYS_ENABLED_STATISTIC(NumFileLookups, "Number of file lookups."); -ALWAYS_ENABLED_STATISTIC(NumDirCacheMisses, - "Number of directory cache misses."); -ALWAYS_ENABLED_STATISTIC(NumFileCacheMisses, "Number of file cache misses."); - //===----------------------------------------------------------------------===// // Common logic. //===----------------------------------------------------------------------===// @@ -656,6 +650,14 @@ StringRef FileManager::getCanonicalName(const void *Entry, StringRef Name) { return CanonicalName; } +void FileManager::AddStats(const FileManager &Other) { + assert(&Other != this && "Collecting stats into the same FileManager"); + NumDirLookups += Other.NumDirLookups; + NumFileLookups += Other.NumFileLookups; + NumDirCacheMisses += Other.NumDirCacheMisses; + NumFileCacheMisses += Other.NumFileCacheMisses; +} + void FileManager::PrintStats() const { llvm::errs() << "\n*** File Manager Stats:\n"; llvm::errs() << UniqueRealFiles.size() << " real files found, " diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index e69adbe75473..df9855a52e61 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -225,6 +225,10 @@ public: bool hasBitIntType() const override { return true; } const char *getBFloat16Mangling() const override { return "u6__bf16"; }; + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64); + } }; class LLVM_LIBRARY_VISIBILITY ARMleTargetInfo : public ARMTargetInfo { diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h index 9376c46cd98c..feeb04f37eeb 100644 --- a/clang/lib/Basic/Targets/AVR.h +++ b/clang/lib/Basic/Targets/AVR.h @@ -175,6 +175,10 @@ public: std::optional handleAsmEscapedChar(char EscChar) const override; StringRef getABI() const override { return ABI; } + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } + protected: std::string CPU; StringRef ABI; diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h index 489f29fc4fea..d19b37dd4df7 100644 --- a/clang/lib/Basic/Targets/BPF.h +++ b/clang/lib/Basic/Targets/BPF.h @@ -113,6 +113,10 @@ public: StringRef CPUName(Name); return isValidCPUName(CPUName); } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h index 7ffa901127e5..b732add77e03 100644 --- a/clang/lib/Basic/Targets/M68k.h +++ b/clang/lib/Basic/Targets/M68k.h @@ -56,6 +56,10 @@ public: BuiltinVaListKind getBuiltinVaListKind() const override; bool setCPU(const std::string &Name) override; CallingConvCheckResult checkCallingConvention(CallingConv CC) const override; + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; } // namespace targets diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index 0d6e4b4d0808..730deb674aa5 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -431,6 +431,10 @@ public: bool validateTarget(DiagnosticsEngine &Diags) const override; bool hasBitIntType() const override { return true; } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index 60bc1dec8f95..cd0f08dfb3bc 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -423,6 +423,10 @@ public: // This is the ELF definition return TargetInfo::PowerABIBuiltinVaList; } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; // Note: ABI differences may eventually require us to have a separate @@ -503,6 +507,10 @@ public: return CCCR_Warning; } } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(128, 128); + } }; class LLVM_LIBRARY_VISIBILITY AIXPPC32TargetInfo : diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h index 78580b5b1c10..d0e9cdc6da07 100644 --- a/clang/lib/Basic/Targets/RISCV.h +++ b/clang/lib/Basic/Targets/RISCV.h @@ -16,7 +16,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/RISCVISAInfo.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/Triple.h" #include @@ -122,6 +122,10 @@ public: void fillValidTuneCPUList(SmallVectorImpl &Values) const override; bool supportsTargetAttributeTune() const override { return true; } ParsedTargetAttr parseTargetAttr(StringRef Str) const override; + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; class LLVM_LIBRARY_VISIBILITY RISCV32TargetInfo : public RISCVTargetInfo { public: diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h index 214fef88e1dc..3357bee33e1a 100644 --- a/clang/lib/Basic/Targets/Sparc.h +++ b/clang/lib/Basic/Targets/Sparc.h @@ -140,6 +140,10 @@ public: CPU = getCPUKind(Name); return CPU != CK_GENERIC; } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(32, 32); + } }; // SPARC v8 is the 32-bit mode selected by Triple::sparc. diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 8e302acd51b8..73d3aa01a043 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -220,6 +220,10 @@ public: int getEHDataRegisterNumber(unsigned RegNo) const override { return RegNo < 4 ? 6 + RegNo : -1; } + + std::pair hardwareInterferenceSizes() const override { + return std::make_pair(256, 256); + } }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index f1c925d90cb6..3d76411f890a 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -47,6 +47,7 @@ bool WebAssemblyTargetInfo::hasFeature(StringRef Feature) const { return llvm::StringSwitch(Feature) .Case("simd128", SIMDLevel >= SIMD128) .Case("relaxed-simd", SIMDLevel >= RelaxedSIMD) + .Case("half-precision", HasHalfPrecision) .Case("nontrapping-fptoint", HasNontrappingFPToInt) .Case("sign-ext", HasSignExt) .Case("exception-handling", HasExceptionHandling) @@ -148,18 +149,19 @@ bool WebAssemblyTargetInfo::initFeatureMap( llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector &FeaturesVec) const { if (CPU == "bleeding-edge") { - Features["nontrapping-fptoint"] = true; - Features["sign-ext"] = true; - Features["bulk-memory"] = true; Features["atomics"] = true; + Features["bulk-memory"] = true; + Features["multimemory"] = true; Features["mutable-globals"] = true; - Features["tail-call"] = true; + Features["nontrapping-fptoint"] = true; Features["reference-types"] = true; - Features["multimemory"] = true; + Features["sign-ext"] = true; + Features["tail-call"] = true; + Features["half-precision"] = true; setSIMDLevel(Features, SIMD128, true); } else if (CPU == "generic") { - Features["sign-ext"] = true; Features["mutable-globals"] = true; + Features["sign-ext"] = true; } return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); @@ -216,6 +218,15 @@ bool WebAssemblyTargetInfo::handleTargetFeatures( HasBulkMemory = false; continue; } + if (Feature == "+half-precision") { + SIMDLevel = std::max(SIMDLevel, SIMD128); + HasHalfPrecision = true; + continue; + } + if (Feature == "-half-precision") { + HasHalfPrecision = false; + continue; + } if (Feature == "+atomics") { HasAtomics = true; continue; diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index 5568aa28eaef..e4c18879182e 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -64,6 +64,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo { bool HasReferenceTypes = false; bool HasExtendedConst = false; bool HasMultiMemory = false; + bool HasHalfPrecision = false; std::string ABI; diff --git a/clang/lib/CIR/CMakeLists.txt b/clang/lib/CIR/CMakeLists.txt index e69de29bb2d1..d2ff200e0da5 100644 --- a/clang/lib/CIR/CMakeLists.txt +++ b/clang/lib/CIR/CMakeLists.txt @@ -0,0 +1,4 @@ +include_directories(${LLVM_MAIN_SRC_DIR}/../mlir/include) +include_directories(${CMAKE_BINARY_DIR}/tools/mlir/include) + +add_subdirectory(Dialect) diff --git a/clang/lib/CIR/Dialect/CMakeLists.txt b/clang/lib/CIR/Dialect/CMakeLists.txt new file mode 100644 index 000000000000..f33061b2d87c --- /dev/null +++ b/clang/lib/CIR/Dialect/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(IR) diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp new file mode 100644 index 000000000000..c2829c3ff2af --- /dev/null +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -0,0 +1,13 @@ +//===- CIRDialect.cpp - MLIR CIR ops implementation -----------------------===// +// +// Part of the LLVM Project, under the Apache 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 CIR dialect and its operations. +// +//===----------------------------------------------------------------------===// + +#include diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt new file mode 100644 index 000000000000..0d7476b55570 --- /dev/null +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -0,0 +1,3 @@ +add_clang_library(MLIRCIR + CIRDialect.cpp + ) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 7e5f2edfc732..a370734e00d3 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -822,8 +822,9 @@ CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); } -const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( - ASTContext &Ctx, const RecordDecl *RD, StringRef Name, uint64_t &Offset) { +const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberFieldAndOffset( + ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FAMDecl, + uint64_t &Offset) { const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel = getLangOpts().getStrictFlexArraysLevel(); uint32_t FieldNo = 0; @@ -832,7 +833,7 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( return nullptr; for (const FieldDecl *FD : RD->fields()) { - if ((Name.empty() || FD->getNameAsString() == Name) && + if ((!FAMDecl || FD == FAMDecl) && Decl::isFlexibleArrayMemberLike( Ctx, FD, FD->getType(), StrictFlexArraysLevel, /*IgnoreTemplateOrMacroSubstitution=*/true)) { @@ -843,8 +844,8 @@ const FieldDecl *CodeGenFunction::FindFlexibleArrayMemberField( QualType Ty = FD->getType(); if (Ty->isRecordType()) { - if (const FieldDecl *Field = FindFlexibleArrayMemberField( - Ctx, Ty->getAsRecordDecl(), Name, Offset)) { + if (const FieldDecl *Field = FindFlexibleArrayMemberFieldAndOffset( + Ctx, Ty->getAsRecordDecl(), FAMDecl, Offset)) { const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); Offset += Layout.getFieldOffset(FieldNo); return Field; @@ -930,12 +931,14 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, // Get the flexible array member Decl. const RecordDecl *OuterRD = nullptr; - std::string FAMName; + const FieldDecl *FAMDecl = nullptr; if (const auto *ME = dyn_cast(Base)) { // Check if \p Base is referencing the FAM itself. const ValueDecl *VD = ME->getMemberDecl(); OuterRD = VD->getDeclContext()->getOuterLexicalRecordContext(); - FAMName = VD->getNameAsString(); + FAMDecl = dyn_cast(VD); + if (!FAMDecl) + return nullptr; } else if (const auto *DRE = dyn_cast(Base)) { // Check if we're pointing to the whole struct. QualType Ty = DRE->getDecl()->getType(); @@ -974,9 +977,11 @@ CodeGenFunction::emitFlexibleArrayMemberSize(const Expr *E, unsigned Type, if (!OuterRD) return nullptr; + // We call FindFlexibleArrayMemberAndOffset even if FAMDecl is non-null to + // get its offset. uint64_t Offset = 0; - const FieldDecl *FAMDecl = - FindFlexibleArrayMemberField(Ctx, OuterRD, FAMName, Offset); + FAMDecl = + FindFlexibleArrayMemberFieldAndOffset(Ctx, OuterRD, FAMDecl, Offset); Offset = Ctx.toCharUnitsFromBits(Offset).getQuantity(); if (!FAMDecl || !FAMDecl->getType()->isCountAttributedType()) @@ -3623,7 +3628,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // frexpl instead of legalizing this type in the BE. if (&getTarget().getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble()) break; - LLVM_FALLTHROUGH; + [[fallthrough]]; } case Builtin::BI__builtin_frexp: case Builtin::BI__builtin_frexpf: @@ -3880,9 +3885,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin_reduce_max: { - auto GetIntrinsicID = [](QualType QT) { + auto GetIntrinsicID = [this](QualType QT) { if (auto *VecTy = QT->getAs()) QT = VecTy->getElementType(); + else if (QT->isSizelessVectorType()) + QT = QT->getSizelessVectorEltType(CGM.getContext()); + if (QT->isSignedIntegerType()) return llvm::Intrinsic::vector_reduce_smax; if (QT->isUnsignedIntegerType()) @@ -3895,9 +3903,12 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, } case Builtin::BI__builtin_reduce_min: { - auto GetIntrinsicID = [](QualType QT) { + auto GetIntrinsicID = [this](QualType QT) { if (auto *VecTy = QT->getAs()) QT = VecTy->getElementType(); + else if (QT->isSizelessVectorType()) + QT = QT->getSizelessVectorEltType(CGM.getContext()); + if (QT->isSignedIntegerType()) return llvm::Intrinsic::vector_reduce_smin; if (QT->isUnsignedIntegerType()) @@ -5361,7 +5372,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ptrauth_auth_and_resign: if (Args[4]->getType()->isPointerTy()) Args[4] = Builder.CreatePtrToInt(Args[4], IntPtrTy); - LLVM_FALLTHROUGH; + [[fallthrough]]; case Builtin::BI__builtin_ptrauth_auth: case Builtin::BI__builtin_ptrauth_sign_unauthenticated: @@ -18845,7 +18856,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_wmma_f16_16x16x16_f16_w32_gfx12: case AMDGPU::BI__builtin_amdgcn_wmma_f16_16x16x16_f16_w64_gfx12: AppendFalseForOpselArg = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case AMDGPU::BI__builtin_amdgcn_wmma_f16_16x16x16_f16_w32: case AMDGPU::BI__builtin_amdgcn_wmma_f16_16x16x16_f16_w64: ArgsForMatchingMatrixTypes = {2, 0}; // CD, AB @@ -18854,7 +18865,7 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, case AMDGPU::BI__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32_gfx12: case AMDGPU::BI__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64_gfx12: AppendFalseForOpselArg = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case AMDGPU::BI__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w32: case AMDGPU::BI__builtin_amdgcn_wmma_bf16_16x16x16_bf16_w64: ArgsForMatchingMatrixTypes = {2, 0}; // CD, AB diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 6c33cc17621f..69548902dc43 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1585,6 +1585,11 @@ bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) { return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet()); } +bool CodeGenModule::ReturnTypeHasInReg(const CGFunctionInfo &FI) { + const auto &RI = FI.getReturnInfo(); + return RI.getInReg(); +} + bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) { return ReturnTypeUsesSRet(FI) && getTargetCodeGenInfo().doesReturnSlotInterfereWithArgs(); @@ -4693,11 +4698,11 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, AggValueSlot Slot = args.isUsingInAlloca() ? createPlaceholderSlot(*this, type) : CreateAggTemp(type, "agg.tmp"); - bool DestroyedInCallee = true, NeedsEHCleanup = true; + bool DestroyedInCallee = true, NeedsCleanup = true; if (const auto *RD = type->getAsCXXRecordDecl()) DestroyedInCallee = RD->hasNonTrivialDestructor(); else - NeedsEHCleanup = needsEHCleanup(type.isDestructedType()); + NeedsCleanup = type.isDestructedType(); if (DestroyedInCallee) Slot.setExternallyDestructed(); @@ -4706,14 +4711,15 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E, RValue RV = Slot.asRValue(); args.add(RV, type); - if (DestroyedInCallee && NeedsEHCleanup) { + if (DestroyedInCallee && NeedsCleanup) { // Create a no-op GEP between the placeholder and the cleanup so we can // RAUW it successfully. It also serves as a marker of the first // instruction where the cleanup is active. - pushFullExprCleanup(EHCleanup, Slot.getAddress(), - type); + pushFullExprCleanup(NormalAndEHCleanup, + Slot.getAddress(), type); // This unreachable is a temporary marker which will be removed later. - llvm::Instruction *IsActive = Builder.CreateUnreachable(); + llvm::Instruction *IsActive = + Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy)); args.addArgCleanupDeactivation(EHStack.stable_begin(), IsActive); } return; diff --git a/clang/lib/CodeGen/CGCleanup.cpp b/clang/lib/CodeGen/CGCleanup.cpp index e6f8e6873004..469e0363b744 100644 --- a/clang/lib/CodeGen/CGCleanup.cpp +++ b/clang/lib/CodeGen/CGCleanup.cpp @@ -634,12 +634,19 @@ static void destroyOptimisticNormalEntry(CodeGenFunction &CGF, /// Pops a cleanup block. If the block includes a normal cleanup, the /// current insertion point is threaded through the cleanup, as are /// any branch fixups on the cleanup. -void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { +void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough, + bool ForDeactivation) { assert(!EHStack.empty() && "cleanup stack is empty!"); assert(isa(*EHStack.begin()) && "top not a cleanup!"); EHCleanupScope &Scope = cast(*EHStack.begin()); assert(Scope.getFixupDepth() <= EHStack.getNumBranchFixups()); + // If we are deactivating a normal cleanup, we need to pretend that the + // fallthrough is unreachable. We restore this IP before returning. + CGBuilderTy::InsertPoint NormalDeactivateOrigIP; + if (ForDeactivation && (Scope.isNormalCleanup() || !getLangOpts().EHAsynch)) { + NormalDeactivateOrigIP = Builder.saveAndClearIP(); + } // Remember activation information. bool IsActive = Scope.isActive(); Address NormalActiveFlag = @@ -667,7 +674,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // - whether there's a fallthrough llvm::BasicBlock *FallthroughSource = Builder.GetInsertBlock(); - bool HasFallthrough = (FallthroughSource != nullptr && IsActive); + bool HasFallthrough = + FallthroughSource != nullptr && (IsActive || HasExistingBranches); // Branch-through fall-throughs leave the insertion point set to the // end of the last cleanup, which points to the current scope. The @@ -692,7 +700,11 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { // If we have a prebranched fallthrough into an inactive normal // cleanup, rewrite it so that it leads to the appropriate place. - if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && !IsActive) { + if (Scope.isNormalCleanup() && HasPrebranchedFallthrough && + !RequiresNormalCleanup) { + // FIXME: Come up with a program which would need forwarding prebranched + // fallthrough and add tests. Otherwise delete this and assert against it. + assert(!IsActive); llvm::BasicBlock *prebranchDest; // If the prebranch is semantically branching through the next @@ -724,6 +736,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { EHStack.popCleanup(); // safe because there are no fixups assert(EHStack.getNumBranchFixups() == 0 || EHStack.hasNormalCleanups()); + if (NormalDeactivateOrigIP.isSet()) + Builder.restoreIP(NormalDeactivateOrigIP); return; } @@ -760,11 +774,19 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { if (!RequiresNormalCleanup) { // Mark CPP scope end for passed-by-value Arg temp // per Windows ABI which is "normally" Cleanup in callee - if (IsEHa && getInvokeDest() && Builder.GetInsertBlock()) { - if (Personality.isMSVCXXPersonality()) + if (IsEHa && getInvokeDest()) { + // If we are deactivating a normal cleanup then we don't have a + // fallthrough. Restore original IP to emit CPP scope ends in the correct + // block. + if (NormalDeactivateOrigIP.isSet()) + Builder.restoreIP(NormalDeactivateOrigIP); + if (Personality.isMSVCXXPersonality() && Builder.GetInsertBlock()) EmitSehCppScopeEnd(); + if (NormalDeactivateOrigIP.isSet()) + NormalDeactivateOrigIP = Builder.saveAndClearIP(); } destroyOptimisticNormalEntry(*this, Scope); + Scope.MarkEmitted(); EHStack.popCleanup(); } else { // If we have a fallthrough and no other need for the cleanup, @@ -781,6 +803,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { } destroyOptimisticNormalEntry(*this, Scope); + Scope.MarkEmitted(); EHStack.popCleanup(); EmitCleanup(*this, Fn, cleanupFlags, NormalActiveFlag); @@ -916,6 +939,7 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { } // IV. Pop the cleanup and emit it. + Scope.MarkEmitted(); EHStack.popCleanup(); assert(EHStack.hasNormalCleanups() == HasEnclosingCleanups); @@ -984,6 +1008,8 @@ void CodeGenFunction::PopCleanupBlock(bool FallthroughIsBranchThrough) { } } + if (NormalDeactivateOrigIP.isSet()) + Builder.restoreIP(NormalDeactivateOrigIP); assert(EHStack.hasNormalCleanups() || EHStack.getNumBranchFixups() == 0); // Emit the EH cleanup if required. @@ -1143,25 +1169,6 @@ void CodeGenFunction::EmitBranchThroughCleanup(JumpDest Dest) { Builder.ClearInsertionPoint(); } -static bool IsUsedAsNormalCleanup(EHScopeStack &EHStack, - EHScopeStack::stable_iterator C) { - // If we needed a normal block for any reason, that counts. - if (cast(*EHStack.find(C)).getNormalBlock()) - return true; - - // Check whether any enclosed cleanups were needed. - for (EHScopeStack::stable_iterator - I = EHStack.getInnermostNormalCleanup(); - I != C; ) { - assert(C.strictlyEncloses(I)); - EHCleanupScope &S = cast(*EHStack.find(I)); - if (S.getNormalBlock()) return true; - I = S.getEnclosingNormalCleanup(); - } - - return false; -} - static bool IsUsedAsEHCleanup(EHScopeStack &EHStack, EHScopeStack::stable_iterator cleanup) { // If we needed an EH block for any reason, that counts. @@ -1210,8 +1217,7 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF, // Calculate whether the cleanup was used: // - as a normal cleanup - if (Scope.isNormalCleanup() && - (isActivatedInConditional || IsUsedAsNormalCleanup(CGF.EHStack, C))) { + if (Scope.isNormalCleanup()) { Scope.setTestFlagInNormalCleanup(); needFlag = true; } @@ -1224,13 +1230,16 @@ static void SetupCleanupBlockActivation(CodeGenFunction &CGF, } // If it hasn't yet been used as either, we're done. - if (!needFlag) return; + if (!needFlag) + return; Address var = Scope.getActiveFlag(); if (!var.isValid()) { + CodeGenFunction::AllocaTrackerRAII AllocaTracker(CGF); var = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), CharUnits::One(), "cleanup.isactive"); Scope.setActiveFlag(var); + Scope.AddAuxAllocas(AllocaTracker.Take()); assert(dominatingIP && "no existing variable and no dominating IP!"); @@ -1273,17 +1282,8 @@ void CodeGenFunction::DeactivateCleanupBlock(EHScopeStack::stable_iterator C, // to the current RunCleanupsScope. if (C == EHStack.stable_begin() && CurrentCleanupScopeDepth.strictlyEncloses(C)) { - // Per comment below, checking EHAsynch is not really necessary - // it's there to assure zero-impact w/o EHAsynch option - if (!Scope.isNormalCleanup() && getLangOpts().EHAsynch) { - PopCleanupBlock(); - } else { - // If it's a normal cleanup, we need to pretend that the - // fallthrough is unreachable. - CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP(); - PopCleanupBlock(); - Builder.restoreIP(SavedIP); - } + PopCleanupBlock(/*FallthroughIsBranchThrough=*/false, + /*ForDeactivation=*/true); return; } diff --git a/clang/lib/CodeGen/CGCleanup.h b/clang/lib/CodeGen/CGCleanup.h index 03e4a29d7b3d..c73c97146abc 100644 --- a/clang/lib/CodeGen/CGCleanup.h +++ b/clang/lib/CodeGen/CGCleanup.h @@ -16,8 +16,11 @@ #include "EHScopeStack.h" #include "Address.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/Instruction.h" namespace llvm { class BasicBlock; @@ -266,6 +269,51 @@ class alignas(8) EHCleanupScope : public EHScope { }; mutable struct ExtInfo *ExtInfo; + /// Erases auxillary allocas and their usages for an unused cleanup. + /// Cleanups should mark these allocas as 'used' if the cleanup is + /// emitted, otherwise these instructions would be erased. + struct AuxillaryAllocas { + SmallVector AuxAllocas; + bool used = false; + + // Records a potentially unused instruction to be erased later. + void Add(llvm::AllocaInst *Alloca) { AuxAllocas.push_back(Alloca); } + + // Mark all recorded instructions as used. These will not be erased later. + void MarkUsed() { + used = true; + AuxAllocas.clear(); + } + + ~AuxillaryAllocas() { + if (used) + return; + llvm::SetVector Uses; + for (auto *Inst : llvm::reverse(AuxAllocas)) + CollectUses(Inst, Uses); + // Delete uses in the reverse order of insertion. + for (auto *I : llvm::reverse(Uses)) + I->eraseFromParent(); + } + + private: + void CollectUses(llvm::Instruction *I, + llvm::SetVector &Uses) { + if (!I || !Uses.insert(I)) + return; + for (auto *User : I->users()) + CollectUses(cast(User), Uses); + } + }; + mutable struct AuxillaryAllocas *AuxAllocas; + + AuxillaryAllocas &getAuxillaryAllocas() { + if (!AuxAllocas) { + AuxAllocas = new struct AuxillaryAllocas(); + } + return *AuxAllocas; + } + /// The number of fixups required by enclosing scopes (not including /// this one). If this is the top cleanup scope, all the fixups /// from this index onwards belong to this scope. @@ -298,7 +346,7 @@ public: EHScopeStack::stable_iterator enclosingEH) : EHScope(EHScope::Cleanup, enclosingEH), EnclosingNormal(enclosingNormal), NormalBlock(nullptr), - ActiveFlag(Address::invalid()), ExtInfo(nullptr), + ActiveFlag(Address::invalid()), ExtInfo(nullptr), AuxAllocas(nullptr), FixupDepth(fixupDepth) { CleanupBits.IsNormalCleanup = isNormal; CleanupBits.IsEHCleanup = isEH; @@ -312,8 +360,15 @@ public: } void Destroy() { + if (AuxAllocas) + delete AuxAllocas; delete ExtInfo; } + void AddAuxAllocas(llvm::SmallVector Allocas) { + for (auto *Alloca : Allocas) + getAuxillaryAllocas().Add(Alloca); + } + void MarkEmitted() { getAuxillaryAllocas().MarkUsed(); } // Objects of EHCleanupScope are not destructed. Use Destroy(). ~EHCleanupScope() = delete; diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp index 93ca711f716f..567e85a02dc6 100644 --- a/clang/lib/CodeGen/CGCoroutine.cpp +++ b/clang/lib/CodeGen/CGCoroutine.cpp @@ -413,10 +413,8 @@ llvm::Function * CodeGenFunction::generateAwaitSuspendWrapper(Twine const &CoroName, Twine const &SuspendPointName, CoroutineSuspendExpr const &S) { - std::string FuncName = "__await_suspend_wrapper_"; - FuncName += CoroName.str(); - FuncName += '_'; - FuncName += SuspendPointName.str(); + std::string FuncName = + (CoroName + ".__await_suspend_wrapper__" + SuspendPointName).str(); ASTContext &C = getContext(); diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 539ded5cca5e..787db3504874 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1372,7 +1372,26 @@ llvm::DIType *CGDebugInfo::CreateType(const TemplateSpecializationType *Ty, SourceLocation Loc = AliasDecl->getLocation(); - if (CGM.getCodeGenOpts().DebugTemplateAlias) { + if (CGM.getCodeGenOpts().DebugTemplateAlias && + // The TemplateSpecializationType doesn't contain any instantiation + // information; dependent template arguments can't be resolved. For now, + // fall back to DW_TAG_typedefs for template aliases that are + // instantiation dependent, e.g.: + // ``` + // template + // using A = int; + // + // template + // struct S { + // using AA = A; // Instantiation dependent. + // AA aa; + // }; + // + // S<0> s; + // ``` + // S::AA's underlying type A is dependent on I so will be emitted as a + // DW_TAG_typedef. + !Ty->isInstantiationDependentType()) { auto ArgVector = ::GetTemplateArgs(TD, Ty); TemplateArgs Args = {TD->getTemplateParameters(), ArgVector}; diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index ce6d6d895607..9cc67cdbe424 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -19,6 +19,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "EHScopeStack.h" #include "PatternInit.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" @@ -35,6 +36,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" #include @@ -2201,6 +2203,27 @@ void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, Address addr, destroyer, useEHCleanupForArray); } +// Pushes a destroy and defers its deactivation until its +// CleanupDeactivationScope is exited. +void CodeGenFunction::pushDestroyAndDeferDeactivation( + QualType::DestructionKind dtorKind, Address addr, QualType type) { + assert(dtorKind && "cannot push destructor for trivial type"); + + CleanupKind cleanupKind = getCleanupKind(dtorKind); + pushDestroyAndDeferDeactivation( + cleanupKind, addr, type, getDestroyer(dtorKind), cleanupKind & EHCleanup); +} + +void CodeGenFunction::pushDestroyAndDeferDeactivation( + CleanupKind cleanupKind, Address addr, QualType type, Destroyer *destroyer, + bool useEHCleanupForArray) { + llvm::Instruction *DominatingIP = + Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy)); + pushDestroy(cleanupKind, addr, type, destroyer, useEHCleanupForArray); + DeferredDeactivationCleanupStack.push_back( + {EHStack.stable_begin(), DominatingIP}); +} + void CodeGenFunction::pushStackRestore(CleanupKind Kind, Address SPMem) { EHStack.pushCleanup(Kind, SPMem); } @@ -2217,39 +2240,48 @@ void CodeGenFunction::pushLifetimeExtendedDestroy(CleanupKind cleanupKind, // If we're not in a conditional branch, we don't need to bother generating a // conditional cleanup. if (!isInConditionalBranch()) { - // Push an EH-only cleanup for the object now. // FIXME: When popping normal cleanups, we need to keep this EH cleanup // around in case a temporary's destructor throws an exception. - if (cleanupKind & EHCleanup) - EHStack.pushCleanup( - static_cast(cleanupKind & ~NormalCleanup), addr, type, - destroyer, useEHCleanupForArray); + // Add the cleanup to the EHStack. After the full-expr, this would be + // deactivated before being popped from the stack. + pushDestroyAndDeferDeactivation(cleanupKind, addr, type, destroyer, + useEHCleanupForArray); + + // Since this is lifetime-extended, push it once again to the EHStack after + // the full expression. return pushCleanupAfterFullExprWithActiveFlag( - cleanupKind, Address::invalid(), addr, type, destroyer, useEHCleanupForArray); + cleanupKind, Address::invalid(), addr, type, destroyer, + useEHCleanupForArray); } // Otherwise, we should only destroy the object if it's been initialized. - // Re-use the active flag and saved address across both the EH and end of - // scope cleanups. - using SavedType = typename DominatingValue
::saved_type; using ConditionalCleanupType = EHScopeStack::ConditionalCleanup; - - Address ActiveFlag = createCleanupActiveFlag(); - SavedType SavedAddr = saveValueInCond(addr); - - if (cleanupKind & EHCleanup) { - EHStack.pushCleanup( - static_cast(cleanupKind & ~NormalCleanup), SavedAddr, type, - destroyer, useEHCleanupForArray); - initFullExprCleanupWithFlag(ActiveFlag); - } - + DominatingValue
::saved_type SavedAddr = saveValueInCond(addr); + + // Remember to emit cleanup if we branch-out before end of full-expression + // (eg: through stmt-expr or coro suspensions). + AllocaTrackerRAII DeactivationAllocas(*this); + Address ActiveFlagForDeactivation = createCleanupActiveFlag(); + + pushCleanupAndDeferDeactivation( + cleanupKind, SavedAddr, type, destroyer, useEHCleanupForArray); + initFullExprCleanupWithFlag(ActiveFlagForDeactivation); + EHCleanupScope &cleanup = cast(*EHStack.begin()); + // Erase the active flag if the cleanup was not emitted. + cleanup.AddAuxAllocas(std::move(DeactivationAllocas).Take()); + + // Since this is lifetime-extended, push it once again to the EHStack after + // the full expression. + // The previous active flag would always be 'false' due to forced deferred + // deactivation. Use a separate flag for lifetime-extension to correctly + // remember if this branch was taken and the object was initialized. + Address ActiveFlagForLifetimeExt = createCleanupActiveFlag(); pushCleanupAfterFullExprWithActiveFlag( - cleanupKind, ActiveFlag, SavedAddr, type, destroyer, + cleanupKind, ActiveFlagForLifetimeExt, SavedAddr, type, destroyer, useEHCleanupForArray); } @@ -2442,9 +2474,9 @@ namespace { }; } // end anonymous namespace -/// pushIrregularPartialArrayCleanup - Push an EH cleanup to destroy -/// already-constructed elements of the given array. The cleanup -/// may be popped with DeactivateCleanupBlock or PopCleanupBlock. +/// pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to +/// destroy already-constructed elements of the given array. The cleanup may be +/// popped with DeactivateCleanupBlock or PopCleanupBlock. /// /// \param elementType - the immediate element type of the array; /// possibly still an array type @@ -2453,10 +2485,9 @@ void CodeGenFunction::pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, QualType elementType, CharUnits elementAlign, Destroyer *destroyer) { - pushFullExprCleanup(EHCleanup, - arrayBegin, arrayEndPointer, - elementType, elementAlign, - destroyer); + pushFullExprCleanup( + NormalAndEHCleanup, arrayBegin, arrayEndPointer, elementType, + elementAlign, destroyer); } /// pushRegularPartialArrayCleanup - Push an EH cleanup to destroy diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 931cb391342e..d96c7bb1e568 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -115,10 +115,16 @@ RawAddress CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align, llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, const Twine &Name, llvm::Value *ArraySize) { + llvm::AllocaInst *Alloca; if (ArraySize) - return Builder.CreateAlloca(Ty, ArraySize, Name); - return new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(), - ArraySize, Name, AllocaInsertPt); + Alloca = Builder.CreateAlloca(Ty, ArraySize, Name); + else + Alloca = new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(), + ArraySize, Name, AllocaInsertPt); + if (Allocas) { + Allocas->Add(Alloca); + } + return Alloca; } /// CreateDefaultAlignTempAlloca - This creates an alloca with the @@ -1621,8 +1627,8 @@ LValue CodeGenFunction::EmitLValueHelper(const Expr *E, return EmitArraySubscriptExpr(cast(E)); case Expr::MatrixSubscriptExprClass: return EmitMatrixSubscriptExpr(cast(E)); - case Expr::OMPArraySectionExprClass: - return EmitOMPArraySectionExpr(cast(E)); + case Expr::ArraySectionExprClass: + return EmitArraySectionExpr(cast(E)); case Expr::ExtVectorElementExprClass: return EmitExtVectorElementExpr(cast(E)); case Expr::CXXThisExprClass: @@ -4363,8 +4369,8 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, QualType BaseTy, QualType ElTy, bool IsLowerBound) { LValue BaseLVal; - if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { - BaseLVal = CGF.EmitOMPArraySectionExpr(ASE, IsLowerBound); + if (auto *ASE = dyn_cast(Base->IgnoreParenImpCasts())) { + BaseLVal = CGF.EmitArraySectionExpr(ASE, IsLowerBound); if (BaseTy->isArrayType()) { Address Addr = BaseLVal.getAddress(CGF); BaseInfo = BaseLVal.getBaseInfo(); @@ -4396,9 +4402,13 @@ static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, return CGF.EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo); } -LValue CodeGenFunction::EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, - bool IsLowerBound) { - QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType(E->getBase()); +LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, + bool IsLowerBound) { + + assert(!E->isOpenACCArraySection() && + "OpenACC Array section codegen not implemented"); + + QualType BaseTy = ArraySectionExpr::getBaseOriginalType(E->getBase()); QualType ResultExprTy; if (auto *AT = getContext().getAsArrayType(BaseTy)) ResultExprTy = AT->getElementType(); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 355fec42be44..44d476976a55 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -15,6 +15,7 @@ #include "CodeGenFunction.h" #include "CodeGenModule.h" #include "ConstantEmitter.h" +#include "EHScopeStack.h" #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" @@ -24,6 +25,7 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instruction.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" using namespace clang; @@ -558,24 +560,27 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, // For that, we'll need an EH cleanup. QualType::DestructionKind dtorKind = elementType.isDestructedType(); Address endOfInit = Address::invalid(); - EHScopeStack::stable_iterator cleanup; - llvm::Instruction *cleanupDominator = nullptr; - if (CGF.needsEHCleanup(dtorKind)) { + CodeGenFunction::CleanupDeactivationScope deactivation(CGF); + + if (dtorKind) { + CodeGenFunction::AllocaTrackerRAII allocaTracker(CGF); // In principle we could tell the cleanup where we are more // directly, but the control flow can get so varied here that it // would actually be quite complex. Therefore we go through an // alloca. + llvm::Instruction *dominatingIP = + Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(CGF.Int8PtrTy)); endOfInit = CGF.CreateTempAlloca(begin->getType(), CGF.getPointerAlign(), "arrayinit.endOfInit"); - cleanupDominator = Builder.CreateStore(begin, endOfInit); + Builder.CreateStore(begin, endOfInit); CGF.pushIrregularPartialArrayCleanup(begin, endOfInit, elementType, elementAlign, CGF.getDestroyer(dtorKind)); - cleanup = CGF.EHStack.stable_begin(); + cast(*CGF.EHStack.find(CGF.EHStack.stable_begin())) + .AddAuxAllocas(allocaTracker.Take()); - // Otherwise, remember that we didn't need a cleanup. - } else { - dtorKind = QualType::DK_none; + CGF.DeferredDeactivationCleanupStack.push_back( + {CGF.EHStack.stable_begin(), dominatingIP}); } llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1); @@ -671,9 +676,6 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType, CGF.EmitBlock(endBB); } - - // Leave the partial-array cleanup if we entered one. - if (dtorKind) CGF.DeactivateCleanupBlock(cleanup, cleanupDominator); } //===----------------------------------------------------------------------===// @@ -1374,9 +1376,8 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) { 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 Cleanups; - llvm::Instruction *CleanupDominator = nullptr; + // initializers throws an exception or contains branch out of the expressions. + CodeGenFunction::CleanupDeactivationScope scope(CGF); CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin(); for (LambdaExpr::const_capture_init_iterator i = E->capture_init_begin(), @@ -1395,28 +1396,12 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) { 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(CGF), CurField->getType(), - CGF.getDestroyer(DtorKind), false); - Cleanups.push_back(CGF.EHStack.stable_begin()); - } + if (DtorKind) + CGF.pushDestroyAndDeferDeactivation( + NormalAndEHCleanup, LV.getAddress(CGF), CurField->getType(), + CGF.getDestroyer(DtorKind), false); } } - - // 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) { @@ -1705,14 +1690,7 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( // We'll need to enter cleanup scopes in case any of the element // initializers throws an exception. SmallVector cleanups; - llvm::Instruction *cleanupDominator = nullptr; - auto addCleanup = [&](const EHScopeStack::stable_iterator &cleanup) { - cleanups.push_back(cleanup); - if (!cleanupDominator) // create placeholder once needed - cleanupDominator = CGF.Builder.CreateAlignedLoad( - CGF.Int8Ty, llvm::Constant::getNullValue(CGF.Int8PtrTy), - CharUnits::One()); - }; + CodeGenFunction::CleanupDeactivationScope DeactivateCleanups(CGF); unsigned curInitIndex = 0; @@ -1735,10 +1713,8 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( CGF.EmitAggExpr(InitExprs[curInitIndex++], AggSlot); if (QualType::DestructionKind dtorKind = - Base.getType().isDestructedType()) { - CGF.pushDestroy(dtorKind, V, Base.getType()); - addCleanup(CGF.EHStack.stable_begin()); - } + Base.getType().isDestructedType()) + CGF.pushDestroyAndDeferDeactivation(dtorKind, V, Base.getType()); } } @@ -1815,10 +1791,10 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( if (QualType::DestructionKind dtorKind = field->getType().isDestructedType()) { assert(LV.isSimple()); - if (CGF.needsEHCleanup(dtorKind)) { - CGF.pushDestroy(EHCleanup, LV.getAddress(CGF), field->getType(), - CGF.getDestroyer(dtorKind), false); - addCleanup(CGF.EHStack.stable_begin()); + if (dtorKind) { + CGF.pushDestroyAndDeferDeactivation( + NormalAndEHCleanup, LV.getAddress(CGF), field->getType(), + CGF.getDestroyer(dtorKind), false); pushedCleanup = true; } } @@ -1831,17 +1807,6 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr( if (GEP->use_empty()) GEP->eraseFromParent(); } - - // Deactivate all the partial cleanups in reverse order, which - // generally means popping them. - assert((cleanupDominator || cleanups.empty()) && - "Missing cleanupDominator before deactivating cleanup blocks"); - 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::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E, diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 673ccef84d67..c18c36d3f3f3 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -1008,8 +1008,8 @@ void CodeGenFunction::EmitNewArrayInitializer( const Expr *Init = E->getInitializer(); Address EndOfInit = Address::invalid(); QualType::DestructionKind DtorKind = ElementType.isDestructedType(); - EHScopeStack::stable_iterator Cleanup; - llvm::Instruction *CleanupDominator = nullptr; + CleanupDeactivationScope deactivation(*this); + bool pushedCleanup = false; CharUnits ElementSize = getContext().getTypeSizeInChars(ElementType); CharUnits ElementAlign = @@ -1105,19 +1105,24 @@ void CodeGenFunction::EmitNewArrayInitializer( } // Enter a partial-destruction Cleanup if necessary. - if (needsEHCleanup(DtorKind)) { + if (DtorKind) { + AllocaTrackerRAII AllocaTracker(*this); // In principle we could tell the Cleanup where we are more // directly, but the control flow can get so varied here that it // would actually be quite complex. Therefore we go through an // alloca. + llvm::Instruction *DominatingIP = + Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy)); EndOfInit = CreateTempAlloca(BeginPtr.getType(), getPointerAlign(), "array.init.end"); - CleanupDominator = - Builder.CreateStore(BeginPtr.emitRawPointer(*this), EndOfInit); pushIrregularPartialArrayCleanup(BeginPtr.emitRawPointer(*this), EndOfInit, ElementType, ElementAlign, getDestroyer(DtorKind)); - Cleanup = EHStack.stable_begin(); + cast(*EHStack.find(EHStack.stable_begin())) + .AddAuxAllocas(AllocaTracker.Take()); + DeferredDeactivationCleanupStack.push_back( + {EHStack.stable_begin(), DominatingIP}); + pushedCleanup = true; } CharUnits StartAlign = CurPtr.getAlignment(); @@ -1164,9 +1169,6 @@ void CodeGenFunction::EmitNewArrayInitializer( // initialization. llvm::ConstantInt *ConstNum = dyn_cast(NumElements); if (ConstNum && ConstNum->getZExtValue() <= InitListElements) { - // If there was a Cleanup, deactivate it. - if (CleanupDominator) - DeactivateCleanupBlock(Cleanup, CleanupDominator); return; } @@ -1281,13 +1283,14 @@ void CodeGenFunction::EmitNewArrayInitializer( Builder.CreateStore(CurPtr.emitRawPointer(*this), EndOfInit); // Enter a partial-destruction Cleanup if necessary. - if (!CleanupDominator && needsEHCleanup(DtorKind)) { - llvm::Value *BeginPtrRaw = BeginPtr.emitRawPointer(*this); - llvm::Value *CurPtrRaw = CurPtr.emitRawPointer(*this); - pushRegularPartialArrayCleanup(BeginPtrRaw, CurPtrRaw, ElementType, + if (!pushedCleanup && needsEHCleanup(DtorKind)) { + llvm::Instruction *DominatingIP = + Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy)); + pushRegularPartialArrayCleanup(BeginPtr.emitRawPointer(*this), + CurPtr.emitRawPointer(*this), ElementType, ElementAlign, getDestroyer(DtorKind)); - Cleanup = EHStack.stable_begin(); - CleanupDominator = Builder.CreateUnreachable(); + DeferredDeactivationCleanupStack.push_back( + {EHStack.stable_begin(), DominatingIP}); } // Emit the initializer into this element. @@ -1295,10 +1298,7 @@ void CodeGenFunction::EmitNewArrayInitializer( AggValueSlot::DoesNotOverlap); // Leave the Cleanup if we entered one. - if (CleanupDominator) { - DeactivateCleanupBlock(Cleanup, CleanupDominator); - CleanupDominator->eraseFromParent(); - } + deactivation.ForceDeactivate(); // Advance to the next element by adjusting the pointer type as necessary. llvm::Value *NextPtr = Builder.CreateConstInBoundsGEP1_32( diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index c924660c5a91..94962091116a 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -564,12 +564,13 @@ class ConstStructBuilder { public: static llvm::Constant *BuildStruct(ConstantEmitter &Emitter, - InitListExpr *ILE, QualType StructTy); + const InitListExpr *ILE, + QualType StructTy); static llvm::Constant *BuildStruct(ConstantEmitter &Emitter, const APValue &Value, QualType ValTy); static bool UpdateStruct(ConstantEmitter &Emitter, ConstantAggregateBuilder &Const, CharUnits Offset, - InitListExpr *Updater); + const InitListExpr *Updater); private: ConstStructBuilder(ConstantEmitter &Emitter, @@ -586,7 +587,7 @@ private: bool AppendBitField(const FieldDecl *Field, uint64_t FieldOffset, llvm::ConstantInt *InitExpr, bool AllowOverwrite = false); - bool Build(InitListExpr *ILE, bool AllowOverwrite); + bool Build(const InitListExpr *ILE, bool AllowOverwrite); bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase, const CXXRecordDecl *VTableClass, CharUnits BaseOffset); llvm::Constant *Finalize(QualType Ty); @@ -635,7 +636,7 @@ bool ConstStructBuilder::AppendBitField( static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, ConstantAggregateBuilder &Const, CharUnits Offset, QualType Type, - InitListExpr *Updater) { + const InitListExpr *Updater) { if (Type->isRecordType()) return ConstStructBuilder::UpdateStruct(Emitter, Const, Offset, Updater); @@ -647,7 +648,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, llvm::Type *ElemTy = Emitter.CGM.getTypes().ConvertTypeForMem(ElemType); llvm::Constant *FillC = nullptr; - if (Expr *Filler = Updater->getArrayFiller()) { + if (const Expr *Filler = Updater->getArrayFiller()) { if (!isa(Filler)) { FillC = Emitter.tryEmitAbstractForMemory(Filler, ElemType); if (!FillC) @@ -658,7 +659,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, unsigned NumElementsToUpdate = FillC ? CAT->getZExtSize() : Updater->getNumInits(); for (unsigned I = 0; I != NumElementsToUpdate; ++I, Offset += ElemSize) { - Expr *Init = nullptr; + const Expr *Init = nullptr; if (I < Updater->getNumInits()) Init = Updater->getInit(I); @@ -667,7 +668,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, return false; } else if (!Init || isa(Init)) { continue; - } else if (InitListExpr *ChildILE = dyn_cast(Init)) { + } else if (const auto *ChildILE = dyn_cast(Init)) { if (!EmitDesignatedInitUpdater(Emitter, Const, Offset, ElemType, ChildILE)) return false; @@ -683,7 +684,7 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter, return true; } -bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) { +bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) { RecordDecl *RD = ILE->getType()->castAs()->getDecl(); const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); @@ -711,7 +712,7 @@ bool ConstStructBuilder::Build(InitListExpr *ILE, bool AllowOverwrite) { // Get the initializer. A struct can include fields without initializers, // we just use explicit null values for them. - Expr *Init = nullptr; + const Expr *Init = nullptr; if (ElementNo < ILE->getNumInits()) Init = ILE->getInit(ElementNo++); if (Init && isa(Init)) @@ -879,7 +880,7 @@ llvm::Constant *ConstStructBuilder::Finalize(QualType Type) { } llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter, - InitListExpr *ILE, + const InitListExpr *ILE, QualType ValTy) { ConstantAggregateBuilder Const(Emitter.CGM); ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero()); @@ -906,7 +907,8 @@ llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter, bool ConstStructBuilder::UpdateStruct(ConstantEmitter &Emitter, ConstantAggregateBuilder &Const, - CharUnits Offset, InitListExpr *Updater) { + CharUnits Offset, + const InitListExpr *Updater) { return ConstStructBuilder(Emitter, Const, Offset) .Build(Updater, /*AllowOverwrite*/ true); } @@ -1013,8 +1015,8 @@ EmitArrayConstant(CodeGenModule &CGM, llvm::ArrayType *DesiredType, // // Constant folding is currently missing support for a few features supported // here: CK_ToUnion, CK_ReinterpretMemberPointer, and DesignatedInitUpdateExpr. -class ConstExprEmitter : - public StmtVisitor { +class ConstExprEmitter + : public ConstStmtVisitor { CodeGenModule &CGM; ConstantEmitter &Emitter; llvm::LLVMContext &VMContext; @@ -1027,43 +1029,42 @@ public: // Visitor Methods //===--------------------------------------------------------------------===// - llvm::Constant *VisitStmt(Stmt *S, QualType T) { - return nullptr; - } + llvm::Constant *VisitStmt(const Stmt *S, QualType T) { return nullptr; } - llvm::Constant *VisitConstantExpr(ConstantExpr *CE, QualType T) { + llvm::Constant *VisitConstantExpr(const ConstantExpr *CE, QualType T) { if (llvm::Constant *Result = Emitter.tryEmitConstantExpr(CE)) return Result; return Visit(CE->getSubExpr(), T); } - llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) { + llvm::Constant *VisitParenExpr(const ParenExpr *PE, QualType T) { return Visit(PE->getSubExpr(), T); } llvm::Constant * - VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE, + VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *PE, QualType T) { return Visit(PE->getReplacement(), T); } - llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE, + llvm::Constant *VisitGenericSelectionExpr(const GenericSelectionExpr *GE, QualType T) { return Visit(GE->getResultExpr(), T); } - llvm::Constant *VisitChooseExpr(ChooseExpr *CE, QualType T) { + llvm::Constant *VisitChooseExpr(const ChooseExpr *CE, QualType T) { return Visit(CE->getChosenSubExpr(), T); } - llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E, QualType T) { + llvm::Constant *VisitCompoundLiteralExpr(const CompoundLiteralExpr *E, + QualType T) { return Visit(E->getInitializer(), T); } - llvm::Constant *VisitCastExpr(CastExpr *E, QualType destType) { + llvm::Constant *VisitCastExpr(const CastExpr *E, QualType destType) { if (const auto *ECE = dyn_cast(E)) CGM.EmitExplicitCastExprType(ECE, Emitter.CGF); - Expr *subExpr = E->getSubExpr(); + const Expr *subExpr = E->getSubExpr(); switch (E->getCastKind()) { case CK_ToUnion: { @@ -1117,7 +1118,8 @@ public: // interesting conversions should be done in Evaluate(). But as a // special case, allow compound literals to support the gcc extension // allowing "struct x {int x;} x = (struct x) {};". - if (auto *E = dyn_cast(subExpr->IgnoreParens())) + if (const auto *E = + dyn_cast(subExpr->IgnoreParens())) return Visit(E->getInitializer(), destType); return nullptr; } @@ -1232,21 +1234,22 @@ public: llvm_unreachable("Invalid CastKind"); } - llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE, QualType T) { + llvm::Constant *VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *DIE, + QualType T) { // No need for a DefaultInitExprScope: we don't handle 'this' in a // constant expression. return Visit(DIE->getExpr(), T); } - llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) { + llvm::Constant *VisitExprWithCleanups(const ExprWithCleanups *E, QualType T) { return Visit(E->getSubExpr(), T); } - llvm::Constant *VisitIntegerLiteral(IntegerLiteral *I, QualType T) { + llvm::Constant *VisitIntegerLiteral(const IntegerLiteral *I, QualType T) { return llvm::ConstantInt::get(CGM.getLLVMContext(), I->getValue()); } - llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) { + llvm::Constant *EmitArrayInitialization(const InitListExpr *ILE, QualType T) { auto *CAT = CGM.getContext().getAsConstantArrayType(ILE->getType()); assert(CAT && "can't emit array init for non-constant-bound array"); unsigned NumInitElements = ILE->getNumInits(); @@ -1260,7 +1263,7 @@ public: // Initialize remaining array elements. llvm::Constant *fillC = nullptr; - if (Expr *filler = ILE->getArrayFiller()) { + if (const Expr *filler = ILE->getArrayFiller()) { fillC = Emitter.tryEmitAbstractForMemory(filler, EltType); if (!fillC) return nullptr; @@ -1275,7 +1278,7 @@ public: llvm::Type *CommonElementType = nullptr; for (unsigned i = 0; i < NumInitableElts; ++i) { - Expr *Init = ILE->getInit(i); + const Expr *Init = ILE->getInit(i); llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType); if (!C) return nullptr; @@ -1292,16 +1295,17 @@ public: fillC); } - llvm::Constant *EmitRecordInitialization(InitListExpr *ILE, QualType T) { + llvm::Constant *EmitRecordInitialization(const InitListExpr *ILE, + QualType T) { return ConstStructBuilder::BuildStruct(Emitter, ILE, T); } - llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E, + llvm::Constant *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E, QualType T) { return CGM.EmitNullConstant(T); } - llvm::Constant *VisitInitListExpr(InitListExpr *ILE, QualType T) { + llvm::Constant *VisitInitListExpr(const InitListExpr *ILE, QualType T) { if (ILE->isTransparent()) return Visit(ILE->getInit(0), T); @@ -1314,8 +1318,9 @@ public: return nullptr; } - llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E, - QualType destType) { + llvm::Constant * + VisitDesignatedInitUpdateExpr(const DesignatedInitUpdateExpr *E, + QualType destType) { auto C = Visit(E->getBase(), destType); if (!C) return nullptr; @@ -1329,12 +1334,13 @@ public: llvm::Type *ValTy = CGM.getTypes().ConvertType(destType); bool HasFlexibleArray = false; - if (auto *RT = destType->getAs()) + if (const auto *RT = destType->getAs()) HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember(); return Const.build(ValTy, HasFlexibleArray); } - llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E, QualType Ty) { + llvm::Constant *VisitCXXConstructExpr(const CXXConstructExpr *E, + QualType Ty) { if (!E->getConstructor()->isTrivial()) return nullptr; @@ -1344,13 +1350,13 @@ public: assert(E->getConstructor()->isCopyOrMoveConstructor() && "trivial ctor has argument but isn't a copy/move ctor"); - Expr *Arg = E->getArg(0); + const Expr *Arg = E->getArg(0); assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) && "argument to copy ctor is of wrong type"); // Look through the temporary; it's just converting the value to an // lvalue to pass it to the constructor. - if (auto *MTE = dyn_cast(Arg)) + if (const auto *MTE = dyn_cast(Arg)) return Visit(MTE->getSubExpr(), Ty); // Don't try to support arbitrary lvalue-to-rvalue conversions for now. return nullptr; @@ -1359,12 +1365,12 @@ public: return CGM.EmitNullConstant(Ty); } - llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) { + llvm::Constant *VisitStringLiteral(const StringLiteral *E, QualType T) { // This is a string literal initializing an array in an initializer. return CGM.GetConstantArrayFromStringLiteral(E); } - llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E, QualType T) { + llvm::Constant *VisitObjCEncodeExpr(const ObjCEncodeExpr *E, QualType T) { // This must be an @encode initializing an array in a static initializer. // Don't emit it as the address of the string, emit the string data itself // as an inline array. @@ -1383,14 +1389,14 @@ public: return Visit(E->getSubExpr(), T); } - llvm::Constant *VisitUnaryMinus(UnaryOperator *U, QualType T) { + llvm::Constant *VisitUnaryMinus(const UnaryOperator *U, QualType T) { if (llvm::Constant *C = Visit(U->getSubExpr(), T)) if (auto *CI = dyn_cast(C)) return llvm::ConstantInt::get(CGM.getLLVMContext(), -CI->getValue()); return nullptr; } - llvm::Constant *VisitPackIndexingExpr(PackIndexingExpr *E, QualType T) { + llvm::Constant *VisitPackIndexingExpr(const PackIndexingExpr *E, QualType T) { return Visit(E->getSelectedExpr(), T); } @@ -1696,8 +1702,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) { if (!destType->isReferenceType()) { QualType nonMemoryDestType = getNonMemoryType(CGM, destType); - if (llvm::Constant *C = ConstExprEmitter(*this).Visit(const_cast(E), - nonMemoryDestType)) + if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, nonMemoryDestType)) return emitForMemory(C, destType); } @@ -1777,8 +1782,7 @@ llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E, assert(!destType->isVoidType() && "can't emit a void constant"); if (!destType->isReferenceType()) - if (llvm::Constant *C = - ConstExprEmitter(*this).Visit(const_cast(E), destType)) + if (llvm::Constant *C = ConstExprEmitter(*this).Visit(E, destType)) return C; Expr::EvalResult Result; @@ -2022,7 +2026,7 @@ ConstantLValue ConstantLValueEmitter::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) { assert(E->isExpressibleAsConstantInitializer() && "this boxed expression can't be emitted as a compile-time constant"); - auto *SL = cast(E->getSubExpr()->IgnoreParenCasts()); + const auto *SL = cast(E->getSubExpr()->IgnoreParenCasts()); return emitConstantObjCStringLiteral(SL, E->getType(), CGM); } @@ -2048,12 +2052,12 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { builtin != Builtin::BI__builtin___NSStringMakeConstantString) return nullptr; - auto literal = cast(E->getArg(0)->IgnoreParenCasts()); + const auto *Literal = cast(E->getArg(0)->IgnoreParenCasts()); if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) { - return CGM.getObjCRuntime().GenerateConstantString(literal); + return CGM.getObjCRuntime().GenerateConstantString(Literal); } else { // FIXME: need to deal with UCN conversion issues. - return CGM.GetAddrOfConstantCFString(literal); + return CGM.GetAddrOfConstantCFString(Literal); } } diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 40a5cd20c3d7..af48e8d2b839 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2330,7 +2330,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { } // Perform VLAT <-> VLST bitcast through memory. - // TODO: since the llvm.experimental.vector.{insert,extract} intrinsics + // TODO: since the llvm.vector.{insert,extract} intrinsics // require the element types of the vectors to be the same, we // need to keep this around for bitcasts between VLAT <-> VLST where // the element types of the vectors are not the same, until we figure diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index 72d1471021ac..0d4800b90a2f 100644 --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -673,8 +673,6 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, setPipelineDisabled(true); break; case LoopHintAttr::UnrollCount: - setUnrollState(LoopAttributes::Disable); - break; case LoopHintAttr::UnrollAndJamCount: case LoopHintAttr::VectorizeWidth: case LoopHintAttr::InterleaveCount: diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 4e7f777ba1d9..43dd38659518 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -2905,23 +2905,29 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF, break; case CodeGenOptions::Mixed: case CodeGenOptions::NonLegacy: + StringRef name = "objc_msgSend"; if (CGM.ReturnTypeUsesFPRet(ResultType)) { - imp = - CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), - "objc_msgSend_fpret") - .getCallee(); + name = "objc_msgSend_fpret"; } 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") - .getCallee(); - } else { - imp = CGM.CreateRuntimeFunction( - llvm::FunctionType::get(IdTy, IdTy, true), "objc_msgSend") - .getCallee(); + name = "objc_msgSend_stret"; + + // The address of the memory block is be passed in x8 for POD type, + // or in x0 for non-POD type (marked as inreg). + bool shouldCheckForInReg = + CGM.getContext() + .getTargetInfo() + .getTriple() + .isWindowsMSVCEnvironment() && + CGM.getContext().getTargetInfo().getTriple().isAArch64(); + if (shouldCheckForInReg && CGM.ReturnTypeHasInReg(MSI.CallInfo)) { + name = "objc_msgSend_stret2"; + } } + // The actual types here don't matter - we're going to bitcast the + // function anyway + imp = CGM.CreateRuntimeFunction(llvm::FunctionType::get(IdTy, IdTy, true), + name) + .getCallee(); } // Reset the receiver in case the lookup modified it diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 2ae11e129c75..e39c7c58d278 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -742,8 +742,8 @@ LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) { LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E) { - if (const auto *OASE = dyn_cast(E)) - return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false); + if (const auto *OASE = dyn_cast(E)) + return CGF.EmitArraySectionExpr(OASE, /*IsLowerBound=*/false); return LValue(); } @@ -800,7 +800,7 @@ void ReductionCodeGen::emitSharedOrigLValue(CodeGenFunction &CGF, unsigned N) { void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) { QualType PrivateType = getPrivateType(N); - bool AsArraySection = isa(ClausesData[N].Ref); + bool AsArraySection = isa(ClausesData[N].Ref); if (!PrivateType->isVariablyModifiedType()) { Sizes.emplace_back( CGF.getTypeSize(OrigAddresses[N].first.getType().getNonReferenceType()), @@ -941,9 +941,9 @@ static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy, static const VarDecl *getBaseDecl(const Expr *Ref, const DeclRefExpr *&DE) { const VarDecl *OrigVD = nullptr; - if (const auto *OASE = dyn_cast(Ref)) { + if (const auto *OASE = dyn_cast(Ref)) { const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); - while (const auto *TempOASE = dyn_cast(Base)) + while (const auto *TempOASE = dyn_cast(Base)) Base = TempOASE->getBase()->IgnoreParenImpCasts(); while (const auto *TempASE = dyn_cast(Base)) Base = TempASE->getBase()->IgnoreParenImpCasts(); @@ -3570,9 +3570,8 @@ getPointerAndSize(CodeGenFunction &CGF, const Expr *E) { SizeVal = CGF.Builder.CreateNUWMul(SizeVal, Sz); } } else if (const auto *ASE = - dyn_cast(E->IgnoreParenImpCasts())) { - LValue UpAddrLVal = - CGF.EmitOMPArraySectionExpr(ASE, /*IsLowerBound=*/false); + dyn_cast(E->IgnoreParenImpCasts())) { + LValue UpAddrLVal = CGF.EmitArraySectionExpr(ASE, /*IsLowerBound=*/false); Address UpAddrAddress = UpAddrLVal.getAddress(CGF); llvm::Value *UpAddr = CGF.Builder.CreateConstGEP1_32( UpAddrAddress.getElementType(), UpAddrAddress.emitRawPointer(CGF), @@ -6672,8 +6671,8 @@ private: // Given that an array section is considered a built-in type, we need to // do the calculation based on the length of the section instead of relying // on CGF.getTypeSize(E->getType()). - if (const auto *OAE = dyn_cast(E)) { - QualType BaseTy = OMPArraySectionExpr::getBaseOriginalType( + if (const auto *OAE = dyn_cast(E)) { + QualType BaseTy = ArraySectionExpr::getBaseOriginalType( OAE->getBase()->IgnoreParenImpCasts()) .getCanonicalType(); @@ -6779,7 +6778,7 @@ private: /// Return true if the provided expression is a final array section. A /// final array section, is one whose length can't be proved to be one. bool isFinalArraySectionExpression(const Expr *E) const { - const auto *OASE = dyn_cast(E); + const auto *OASE = dyn_cast(E); // It is not an array section and therefore not a unity-size one. if (!OASE) @@ -6795,7 +6794,7 @@ private: // for this dimension. Also, we should always expect a length if the // base type is pointer. if (!Length) { - QualType BaseQTy = OMPArraySectionExpr::getBaseOriginalType( + QualType BaseQTy = ArraySectionExpr::getBaseOriginalType( OASE->getBase()->IgnoreParenImpCasts()) .getCanonicalType(); if (const auto *ATy = dyn_cast(BaseQTy.getTypePtr())) @@ -7027,7 +7026,7 @@ private: Address BP = Address::invalid(); const Expr *AssocExpr = I->getAssociatedExpression(); const auto *AE = dyn_cast(AssocExpr); - const auto *OASE = dyn_cast(AssocExpr); + const auto *OASE = dyn_cast(AssocExpr); const auto *OAShE = dyn_cast(AssocExpr); if (isa(AssocExpr)) { @@ -7179,14 +7178,14 @@ private: // special treatment for array sections given that they are built-in // types. const auto *OASE = - dyn_cast(I->getAssociatedExpression()); + dyn_cast(I->getAssociatedExpression()); const auto *OAShE = dyn_cast(I->getAssociatedExpression()); const auto *UO = dyn_cast(I->getAssociatedExpression()); const auto *BO = dyn_cast(I->getAssociatedExpression()); bool IsPointer = OAShE || - (OASE && OMPArraySectionExpr::getBaseOriginalType(OASE) + (OASE && ArraySectionExpr::getBaseOriginalType(OASE) .getCanonicalType() ->isAnyPointerType()) || I->getAssociatedExpression()->getType()->isAnyPointerType(); @@ -7207,7 +7206,7 @@ private: assert((Next == CE || isa(Next->getAssociatedExpression()) || isa(Next->getAssociatedExpression()) || - isa(Next->getAssociatedExpression()) || + isa(Next->getAssociatedExpression()) || isa(Next->getAssociatedExpression()) || isa(Next->getAssociatedExpression()) || isa(Next->getAssociatedExpression())) && @@ -7439,7 +7438,7 @@ private: PartialStruct.LowestElem = {FieldIndex, LowestElem}; if (IsFinalArraySection) { Address HB = - CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false) + CGF.EmitArraySectionExpr(OASE, /*IsLowerBound=*/false) .getAddress(CGF); PartialStruct.HighestElem = {FieldIndex, HB}; } else { @@ -7452,7 +7451,7 @@ private: } else if (FieldIndex > PartialStruct.HighestElem.first) { if (IsFinalArraySection) { Address HB = - CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false) + CGF.EmitArraySectionExpr(OASE, /*IsLowerBound=*/false) .getAddress(CGF); PartialStruct.HighestElem = {FieldIndex, HB}; } else { @@ -7510,12 +7509,12 @@ private: for (const OMPClauseMappableExprCommon::MappableComponent &Component : Components) { const Expr *AssocExpr = Component.getAssociatedExpression(); - const auto *OASE = dyn_cast(AssocExpr); + const auto *OASE = dyn_cast(AssocExpr); if (!OASE) continue; - QualType Ty = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + QualType Ty = ArraySectionExpr::getBaseOriginalType(OASE->getBase()); auto *CAT = Context.getAsConstantArrayType(Ty); auto *VAT = Context.getAsVariableArrayType(Ty); @@ -7589,7 +7588,7 @@ private: continue; } - const auto *OASE = dyn_cast(AssocExpr); + const auto *OASE = dyn_cast(AssocExpr); if (!OASE) continue; @@ -8780,7 +8779,7 @@ static ValueDecl *getDeclFromThisExpr(const Expr *E) { if (!E) return nullptr; - if (const auto *OASE = dyn_cast(E->IgnoreParenCasts())) + if (const auto *OASE = dyn_cast(E->IgnoreParenCasts())) if (const MemberExpr *ME = dyn_cast(OASE->getBase()->IgnoreParenImpCasts())) return ME->getMemberDecl(); diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp index eb716520e5ff..87496c8e488c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp @@ -92,9 +92,9 @@ static const ValueDecl *getPrivateItem(const Expr *RefExpr) { while (const auto *TempASE = dyn_cast(Base)) Base = TempASE->getBase()->IgnoreParenImpCasts(); RefExpr = Base; - } else if (auto *OASE = dyn_cast(RefExpr)) { + } else if (auto *OASE = dyn_cast(RefExpr)) { const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); - while (const auto *TempOASE = dyn_cast(Base)) + while (const auto *TempOASE = dyn_cast(Base)) Base = TempOASE->getBase()->IgnoreParenImpCasts(); while (const auto *TempASE = dyn_cast(Base)) Base = TempASE->getBase()->IgnoreParenImpCasts(); diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index a0a8a07c76ba..ef3aa3a8e0dc 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1256,7 +1256,7 @@ void CodeGenFunction::EmitOMPReductionClauseInit( const auto *LHSVD = cast(cast(*ILHS)->getDecl()); const auto *RHSVD = cast(cast(*IRHS)->getDecl()); QualType Type = PrivateVD->getType(); - bool isaOMPArraySectionExpr = isa(IRef); + bool isaOMPArraySectionExpr = isa(IRef); if (isaOMPArraySectionExpr && Type->isVariablyModifiedType()) { // Store the address of the original variable associated with the LHS // implicit variable. @@ -7289,7 +7289,7 @@ void CodeGenFunction::EmitOMPUseDevicePtrClause( static const VarDecl *getBaseDecl(const Expr *Ref) { const Expr *Base = Ref->IgnoreParenImpCasts(); - while (const auto *OASE = dyn_cast(Base)) + while (const auto *OASE = dyn_cast(Base)) Base = OASE->getBase()->IgnoreParenImpCasts(); while (const auto *ASE = dyn_cast(Base)) Base = ASE->getBase()->IgnoreParenImpCasts(); diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 86a6ddd80cc1..87766a758311 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -91,6 +91,8 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) CodeGenFunction::~CodeGenFunction() { assert(LifetimeExtendedCleanupStack.empty() && "failed to emit a cleanup"); + assert(DeferredDeactivationCleanupStack.empty() && + "missed to deactivate a cleanup"); if (getLangOpts().OpenMP && CurFn) CGM.getOpenMPRuntime().functionFinished(*this); @@ -346,6 +348,10 @@ static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB) { void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); + assert(LifetimeExtendedCleanupStack.empty() && + "mismatched push/pop of cleanups in EHStack!"); + assert(DeferredDeactivationCleanupStack.empty() && + "mismatched activate/deactivate of cleanups!"); bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0 && NumSimpleReturnExprs == NumReturnExprs diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index ff1873325d40..6e7417fc7f52 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -39,6 +39,7 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/Debug.h" #include "llvm/Transforms/Utils/SanitizerStats.h" @@ -670,6 +671,51 @@ public: EHScopeStack EHStack; llvm::SmallVector LifetimeExtendedCleanupStack; + + // A stack of cleanups which were added to EHStack but have to be deactivated + // later before being popped or emitted. These are usually deactivated on + // exiting a `CleanupDeactivationScope` scope. For instance, after a + // full-expr. + // + // These are specially useful for correctly emitting cleanups while + // encountering branches out of expression (through stmt-expr or coroutine + // suspensions). + struct DeferredDeactivateCleanup { + EHScopeStack::stable_iterator Cleanup; + llvm::Instruction *DominatingIP; + }; + llvm::SmallVector DeferredDeactivationCleanupStack; + + // Enters a new scope for capturing cleanups which are deferred to be + // deactivated, all of which will be deactivated once the scope is exited. + struct CleanupDeactivationScope { + CodeGenFunction &CGF; + size_t OldDeactivateCleanupStackSize; + bool Deactivated; + CleanupDeactivationScope(CodeGenFunction &CGF) + : CGF(CGF), OldDeactivateCleanupStackSize( + CGF.DeferredDeactivationCleanupStack.size()), + Deactivated(false) {} + + void ForceDeactivate() { + assert(!Deactivated && "Deactivating already deactivated scope"); + auto &Stack = CGF.DeferredDeactivationCleanupStack; + for (size_t I = Stack.size(); I > OldDeactivateCleanupStackSize; I--) { + CGF.DeactivateCleanupBlock(Stack[I - 1].Cleanup, + Stack[I - 1].DominatingIP); + Stack[I - 1].DominatingIP->eraseFromParent(); + } + Stack.resize(OldDeactivateCleanupStackSize); + Deactivated = true; + } + + ~CleanupDeactivationScope() { + if (Deactivated) + return; + ForceDeactivate(); + } + }; + llvm::SmallVector SEHTryEpilogueStack; llvm::Instruction *CurrentFuncletPad = nullptr; @@ -875,6 +921,19 @@ public: new (Buffer + sizeof(Header) + sizeof(T)) RawAddress(ActiveFlag); } + // Push a cleanup onto EHStack and deactivate it later. It is usually + // deactivated when exiting a `CleanupDeactivationScope` (for example: after a + // full expression). + template + void pushCleanupAndDeferDeactivation(CleanupKind Kind, As... A) { + // Placeholder dominating IP for this cleanup. + llvm::Instruction *DominatingIP = + Builder.CreateFlagLoad(llvm::Constant::getNullValue(Int8PtrTy)); + EHStack.pushCleanup(Kind, A...); + DeferredDeactivationCleanupStack.push_back( + {EHStack.stable_begin(), DominatingIP}); + } + /// Set up the last cleanup that was pushed as a conditional /// full-expression cleanup. void initFullExprCleanup() { @@ -898,7 +957,8 @@ public: /// PopCleanupBlock - Will pop the cleanup entry on the stack and /// process all branch fixups. - void PopCleanupBlock(bool FallThroughIsBranchThrough = false); + void PopCleanupBlock(bool FallThroughIsBranchThrough = false, + bool ForDeactivation = false); /// DeactivateCleanupBlock - Deactivates the given cleanup block. /// The block cannot be reactivated. Pops it if it's the top of the @@ -926,6 +986,7 @@ public: class RunCleanupsScope { EHScopeStack::stable_iterator CleanupStackDepth, OldCleanupScopeDepth; size_t LifetimeExtendedCleanupStackSize; + CleanupDeactivationScope DeactivateCleanups; bool OldDidCallStackSave; protected: bool PerformCleanup; @@ -940,8 +1001,7 @@ public: public: /// Enter a new cleanup scope. explicit RunCleanupsScope(CodeGenFunction &CGF) - : PerformCleanup(true), CGF(CGF) - { + : DeactivateCleanups(CGF), PerformCleanup(true), CGF(CGF) { CleanupStackDepth = CGF.EHStack.stable_begin(); LifetimeExtendedCleanupStackSize = CGF.LifetimeExtendedCleanupStack.size(); @@ -971,6 +1031,7 @@ public: void ForceCleanup(std::initializer_list ValuesToReload = {}) { assert(PerformCleanup && "Already forced cleanup"); CGF.DidCallStackSave = OldDidCallStackSave; + DeactivateCleanups.ForceDeactivate(); CGF.PopCleanupBlocks(CleanupStackDepth, LifetimeExtendedCleanupStackSize, ValuesToReload); PerformCleanup = false; @@ -2160,6 +2221,11 @@ public: Address addr, QualType type); void pushDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); + void pushDestroyAndDeferDeactivation(QualType::DestructionKind dtorKind, + Address addr, QualType type); + void pushDestroyAndDeferDeactivation(CleanupKind cleanupKind, Address addr, + QualType type, Destroyer *destroyer, + bool useEHCleanupForArray); void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray); @@ -2698,6 +2764,33 @@ public: TBAAAccessInfo *TBAAInfo = nullptr); LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy); +private: + struct AllocaTracker { + void Add(llvm::AllocaInst *I) { Allocas.push_back(I); } + llvm::SmallVector Take() { return std::move(Allocas); } + + private: + llvm::SmallVector Allocas; + }; + AllocaTracker *Allocas = nullptr; + +public: + // Captures all the allocas created during the scope of its RAII object. + struct AllocaTrackerRAII { + AllocaTrackerRAII(CodeGenFunction &CGF) + : CGF(CGF), OldTracker(CGF.Allocas) { + CGF.Allocas = &Tracker; + } + ~AllocaTrackerRAII() { CGF.Allocas = OldTracker; } + + llvm::SmallVector Take() { return Tracker.Take(); } + + private: + CodeGenFunction &CGF; + AllocaTracker *OldTracker; + AllocaTracker Tracker; + }; + /// CreateTempAlloca - This creates an alloca and inserts it into the entry /// block if \p ArraySize is nullptr, otherwise inserts it at the current /// insertion point of the builder. The caller is responsible for setting an @@ -3204,12 +3297,12 @@ public: llvm::Value *Index, QualType IndexType, QualType IndexedType, bool Accessed); - // Find a struct's flexible array member. It may be embedded inside multiple - // sub-structs, but must still be the last field. - const FieldDecl *FindFlexibleArrayMemberField(ASTContext &Ctx, - const RecordDecl *RD, - StringRef Name, - uint64_t &Offset); + // Find a struct's flexible array member and get its offset. It may be + // embedded inside multiple sub-structs, but must still be the last field. + const FieldDecl * + FindFlexibleArrayMemberFieldAndOffset(ASTContext &Ctx, const RecordDecl *RD, + const FieldDecl *FAMDecl, + uint64_t &Offset); /// Find the FieldDecl specified in a FAM's "counted_by" attribute. Returns /// \p nullptr if either the attribute or the field doesn't exist. @@ -4169,8 +4262,8 @@ public: LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E, bool Accessed = false); LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E); - LValue EmitOMPArraySectionExpr(const OMPArraySectionExpr *E, - bool IsLowerBound = true); + LValue EmitArraySectionExpr(const ArraySectionExpr *E, + bool IsLowerBound = true); LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E); LValue EmitMemberExpr(const MemberExpr *E); LValue EmitObjCIsaExpr(const ObjCIsaExpr *E); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 0c447b20cef4..d085e735ecb4 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -68,9 +68,9 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/TimeProfiler.h" #include "llvm/Support/xxhash.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/Triple.h" #include "llvm/TargetParser/X86TargetParser.h" #include diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 1cc447765e2c..be43a18fc608 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1241,6 +1241,9 @@ public: /// Return true iff the given type uses 'sret' when used as a return type. bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); + /// Return true iff the given type has `inreg` set. + bool ReturnTypeHasInReg(const CGFunctionInfo &FI); + /// Return true iff the given type uses an argument slot when 'sret' is used /// as a return type. bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 1568b6e6275b..e8d75eda029e 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -409,7 +409,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { break; case BuiltinType::LongDouble: LongDoubleReferenced = true; - LLVM_FALLTHROUGH; + [[fallthrough]]; case BuiltinType::BFloat16: case BuiltinType::Float: case BuiltinType::Double: diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 0da92001e08c..76b7b9fdfb4f 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -87,12 +87,12 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" -#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/Regex.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include // ::getenv #include #include diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 8bfe9f02a091..6a4f2548c0bf 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -1192,7 +1192,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, BinaryMetadataIgnorelistFiles); } - if (TC.getTriple().isOSWindows() && needsUbsanRt()) { + if (TC.getTriple().isOSWindows() && needsUbsanRt() && + Args.hasFlag(options::OPT_frtlib_defaultlib, + options::OPT_fno_rtlib_defaultlib, true)) { // Instruct the code generator to embed linker directives in the object file // that cause the required runtime libraries to be linked. CmdArgs.push_back( @@ -1203,7 +1205,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, "--dependent-lib=" + TC.getCompilerRTBasename(Args, "ubsan_standalone_cxx"))); } - if (TC.getTriple().isOSWindows() && needsStatsRt()) { + if (TC.getTriple().isOSWindows() && needsStatsRt() && + Args.hasFlag(options::OPT_frtlib_defaultlib, + options::OPT_fno_rtlib_defaultlib, true)) { CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats_client"))); diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 237092ed07e5..341d6202a9ca 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1307,9 +1307,14 @@ void ToolChain::AddCCKextLibArgs(const ArgList &Args, bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, std::string &Path) const { + // Don't implicitly link in mode-changing libraries in a shared library, since + // this can have very deleterious effects. See the various links from + // https://github.com/llvm/llvm-project/issues/57589 for more information. + bool Default = !Args.hasArgNoClaim(options::OPT_shared); + // Do not check for -fno-fast-math or -fno-unsafe-math when -Ofast passed // (to keep the linker options consistent with gcc and clang itself). - if (!isOptimizationLevelFast(Args)) { + if (Default && !isOptimizationLevelFast(Args)) { // Check if -ffast-math or -funsafe-math. Arg *A = Args.getLastArg(options::OPT_ffast_math, options::OPT_fno_fast_math, @@ -1318,8 +1323,14 @@ bool ToolChain::isFastMathRuntimeAvailable(const ArgList &Args, if (!A || A->getOption().getID() == options::OPT_fno_fast_math || A->getOption().getID() == options::OPT_fno_unsafe_math_optimizations) - return false; + Default = false; } + + // Whatever decision came as a result of the above implicit settings, either + // -mdaz-ftz or -mno-daz-ftz is capable of overriding it. + if (!Args.hasFlag(options::OPT_mdaz_ftz, options::OPT_mno_daz_ftz, Default)) + return false; + // If crtfastmath.o exists add it to the arguments. Path = GetFilePath("crtfastmath.o"); return (Path != "crtfastmath.o"); // Not found. diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp index c1b350893b37..aab98506adb9 100644 --- a/clang/lib/Driver/ToolChains/AIX.cpp +++ b/clang/lib/Driver/ToolChains/AIX.cpp @@ -376,9 +376,7 @@ void AIX::AddOpenMPIncludeArgs(const ArgList &DriverArgs, addSystemInclude(DriverArgs, CC1Args, PathOpenMP.str()); break; case Driver::OMPRT_IOMP5: - LLVM_FALLTHROUGH; case Driver::OMPRT_GOMP: - LLVM_FALLTHROUGH; case Driver::OMPRT_Unknown: // Unknown / unsupported include paths. break; diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 4e6362a0f406..07965b487ea7 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -617,8 +617,7 @@ void amdgpu::Linker::ConstructJob(Compilation &C, const JobAction &JA, const InputInfoList &Inputs, const ArgList &Args, const char *LinkingOutput) const { - - std::string Linker = getToolChain().GetProgramPath(getShortName()); + std::string Linker = getToolChain().GetLinkerPath(); ArgStringList CmdArgs; CmdArgs.push_back("--no-undefined"); CmdArgs.push_back("-shared"); diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp index 96b3cc3bb8ff..2e2bce849467 100644 --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -15,9 +15,9 @@ #include "clang/Driver/Options.h" #include "llvm/Option/ArgList.h" #include "llvm/Support/Error.h" -#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" using namespace clang::driver; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 5894a48e0e37..651a2b5aac36 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -54,11 +54,11 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" -#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/YAMLParser.h" #include "llvm/TargetParser/ARMTargetParserCommon.h" #include "llvm/TargetParser/Host.h" #include "llvm/TargetParser/LoongArchTargetParser.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include @@ -637,7 +637,9 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, ProfileGenerateArg->getValue())); // The default is to use Clang Instrumentation. CmdArgs.push_back("-fprofile-instrument=clang"); - if (TC.getTriple().isWindowsMSVCEnvironment()) { + if (TC.getTriple().isWindowsMSVCEnvironment() && + Args.hasFlag(options::OPT_frtlib_defaultlib, + options::OPT_fno_rtlib_defaultlib, true)) { // Add dependent lib for clang_rt.profile CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile"))); @@ -656,7 +658,9 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, CmdArgs.push_back("-fprofile-instrument=csllvm"); } if (PGOGenArg) { - if (TC.getTriple().isWindowsMSVCEnvironment()) { + if (TC.getTriple().isWindowsMSVCEnvironment() && + Args.hasFlag(options::OPT_frtlib_defaultlib, + options::OPT_fno_rtlib_defaultlib, true)) { // Add dependent lib for clang_rt.profile CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "profile"))); @@ -831,46 +835,6 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, } } -/// Check whether the given input tree contains any compilation actions. -static bool ContainsCompileAction(const Action *A) { - if (isa(A) || isa(A)) - return true; - - return llvm::any_of(A->inputs(), ContainsCompileAction); -} - -/// Check if -relax-all should be passed to the internal assembler. -/// This is done by default when compiling non-assembler source with -O0. -static bool UseRelaxAll(Compilation &C, const ArgList &Args) { - bool RelaxDefault = true; - - if (Arg *A = Args.getLastArg(options::OPT_O_Group)) - RelaxDefault = A->getOption().matches(options::OPT_O0); - - // RISC-V requires an indirect jump for offsets larger than 1MiB. This cannot - // be done by assembler branch relaxation as it needs a free temporary - // register. Because of this, branch relaxation is handled by a MachineIR - // pass before the assembler. Forcing assembler branch relaxation for -O0 - // makes the MachineIR branch relaxation inaccurate and it will miss cases - // where an indirect branch is necessary. To avoid this issue we are - // sacrificing the compile time improvement of using -mrelax-all for -O0. - if (C.getDefaultToolChain().getTriple().isRISCV()) - RelaxDefault = false; - - if (RelaxDefault) { - RelaxDefault = false; - for (const auto &Act : C.getActions()) { - if (ContainsCompileAction(Act)) { - RelaxDefault = true; - break; - } - } - } - - return Args.hasFlag(options::OPT_mrelax_all, options::OPT_mno_relax_all, - RelaxDefault); -} - static void RenderDebugEnablingArgs(const ArgList &Args, ArgStringList &CmdArgs, llvm::codegenoptions::DebugInfoKind DebugInfoKind, @@ -2468,8 +2432,16 @@ static void CollectArgsForIntegratedAssembler(Compilation &C, const ArgList &Args, ArgStringList &CmdArgs, const Driver &D) { - if (UseRelaxAll(C, Args)) - CmdArgs.push_back("-mrelax-all"); + // Default to -mno-relax-all. + // + // Note: RISC-V requires an indirect jump for offsets larger than 1MiB. This + // cannot be done by assembler branch relaxation as it needs a free temporary + // register. Because of this, branch relaxation is handled by a MachineIR pass + // before the assembler. Forcing assembler branch relaxation for -O0 makes the + // MachineIR branch relaxation inaccurate and it will miss cases where an + // indirect branch is necessary. + Args.addOptInFlag(CmdArgs, options::OPT_mrelax_all, + options::OPT_mno_relax_all); // Only default to -mincremental-linker-compatible if we think we are // targeting the MSVC linker. diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index b65b96db16bd..fec11c7e716f 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1191,118 +1191,10 @@ bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs, return true; } -/// Determines if --whole-archive is active in the list of arguments. -static bool isWholeArchivePresent(const ArgList &Args) { - bool WholeArchiveActive = false; - for (auto *Arg : Args.filtered(options::OPT_Wl_COMMA)) { - if (Arg) { - for (StringRef ArgValue : Arg->getValues()) { - if (ArgValue == "--whole-archive") - WholeArchiveActive = true; - if (ArgValue == "--no-whole-archive") - WholeArchiveActive = false; - } - } - } - - return WholeArchiveActive; -} - -/// Determine if driver is invoked to create a shared object library (-static) -static bool isSharedLinkage(const ArgList &Args) { - return Args.hasArg(options::OPT_shared); -} - -/// Determine if driver is invoked to create a static object library (-shared) -static bool isStaticLinkage(const ArgList &Args) { - return Args.hasArg(options::OPT_static); -} - -/// Add Fortran runtime libs for MSVC -static void addFortranRuntimeLibsMSVC(const ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) { - unsigned RTOptionID = options::OPT__SLASH_MT; - if (auto *rtl = Args.getLastArg(options::OPT_fms_runtime_lib_EQ)) { - RTOptionID = llvm::StringSwitch(rtl->getValue()) - .Case("static", options::OPT__SLASH_MT) - .Case("static_dbg", options::OPT__SLASH_MTd) - .Case("dll", options::OPT__SLASH_MD) - .Case("dll_dbg", options::OPT__SLASH_MDd) - .Default(options::OPT__SLASH_MT); - } - switch (RTOptionID) { - case options::OPT__SLASH_MT: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static.lib"); - break; - case options::OPT__SLASH_MTd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.static_dbg.lib"); - break; - case options::OPT__SLASH_MD: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic.lib"); - break; - case options::OPT__SLASH_MDd: - CmdArgs.push_back("/WHOLEARCHIVE:Fortran_main.dynamic_dbg.lib"); - break; - } -} - -// Add FortranMain runtime lib -static void addFortranMain(const ToolChain &TC, const ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) { - // 0. Shared-library linkage - // If we are attempting to link a library, we should not add - // -lFortran_main.a to the link line, as the `main` symbol is not - // required for a library and should also be provided by one of - // the translation units of the code that this shared library - // will be linked against eventually. - if (isSharedLinkage(Args) || isStaticLinkage(Args)) { - return; - } - - // 1. MSVC - if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { - addFortranRuntimeLibsMSVC(Args, CmdArgs); - return; - } - - // 2. GNU and similar - const Driver &D = TC.getDriver(); - const char *FortranMainLinkFlag = "-lFortran_main"; - - // Warn if the user added `-lFortran_main` - this library is an implementation - // detail of Flang and should be handled automaticaly by the driver. - for (const char *arg : CmdArgs) { - if (strncmp(arg, FortranMainLinkFlag, strlen(FortranMainLinkFlag)) == 0) - D.Diag(diag::warn_drv_deprecated_custom) - << FortranMainLinkFlag - << "see the Flang driver documentation for correct usage"; - } - - // The --whole-archive option needs to be part of the link line to make - // sure that the main() function from Fortran_main.a is pulled in by the - // linker. However, it shouldn't be used if it's already active. - // TODO: Find an equivalent of `--whole-archive` for Darwin and AIX. - if (!isWholeArchivePresent(Args) && !TC.getTriple().isMacOSX() && - !TC.getTriple().isOSAIX()) { - CmdArgs.push_back("--whole-archive"); - CmdArgs.push_back(FortranMainLinkFlag); - CmdArgs.push_back("--no-whole-archive"); - return; - } - - CmdArgs.push_back(FortranMainLinkFlag); -} - /// Add Fortran runtime libs void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args, llvm::opt::ArgStringList &CmdArgs) { - // 1. Link FortranMain - // FortranMain depends on FortranRuntime, so needs to be listed first. If - // -fno-fortran-main has been passed, skip linking Fortran_main.a - if (!Args.hasArg(options::OPT_no_fortran_main)) - addFortranMain(TC, Args, CmdArgs); - - // 2. Link FortranRuntime and FortranDecimal + // Link FortranRuntime and FortranDecimal // These are handled earlier on Windows by telling the frontend driver to // add the correct libraries to link against as dependents in the object // file. diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index abe0b9316760..8955b9fb653c 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -15,7 +15,7 @@ #include "llvm/Frontend/Debug/Options.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" -#include "llvm/Support/RISCVISAInfo.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/RISCVTargetParser.h" #include @@ -282,7 +282,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, assert(TC.getTriple().isKnownWindowsMSVCEnvironment() && "can only add VS runtime library on Windows!"); // if -fno-fortran-main has been passed, skip linking Fortran_main.a - bool LinkFortranMain = !Args.hasArg(options::OPT_no_fortran_main); if (TC.getTriple().isKnownWindowsMSVCEnvironment()) { CmdArgs.push_back(Args.MakeArgString( "--dependent-lib=" + TC.getCompilerRTBasename(Args, "builtins"))); @@ -300,8 +299,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, case options::OPT__SLASH_MT: CmdArgs.push_back("-D_MT"); CmdArgs.push_back("--dependent-lib=libcmt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static.lib"); break; @@ -309,8 +306,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("--dependent-lib=libcmtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.static_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.static_dbg.lib"); break; @@ -318,8 +313,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_MT"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrt"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic.lib"); break; @@ -328,8 +321,6 @@ static void processVSRuntimeLibrary(const ToolChain &TC, const ArgList &Args, CmdArgs.push_back("-D_DEBUG"); CmdArgs.push_back("-D_DLL"); CmdArgs.push_back("--dependent-lib=msvcrtd"); - if (LinkFortranMain) - CmdArgs.push_back("--dependent-lib=Fortran_main.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranRuntime.dynamic_dbg.lib"); CmdArgs.push_back("--dependent-lib=FortranDecimal.dynamic_dbg.lib"); break; diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index dedbfac6cb25..9849c59685cc 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -30,8 +30,8 @@ #include "llvm/Option/ArgList.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/Path.h" -#include "llvm/Support/RISCVISAInfo.h" #include "llvm/Support/VirtualFileSystem.h" +#include "llvm/TargetParser/RISCVISAInfo.h" #include "llvm/TargetParser/TargetParser.h" #include @@ -1796,9 +1796,7 @@ selectRISCVMultilib(const MultilibSet &RISCVMultilibSet, StringRef Arch, } auto &MLConfigISAInfo = *MLConfigParseResult; - const llvm::RISCVISAInfo::OrderedExtensionMap &MLConfigArchExts = - MLConfigISAInfo->getExtensions(); - for (auto MLConfigArchExt : MLConfigArchExts) { + for (auto &MLConfigArchExt : MLConfigISAInfo->getExtensions()) { auto ExtName = MLConfigArchExt.first; NewMultilib.flag(Twine("-", ExtName).str()); diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index fb65881061ef..db2c20d7b461 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -842,25 +842,6 @@ void Linux::addProfileRTLibs(const llvm::opt::ArgList &Args, ToolChain::addProfileRTLibs(Args, CmdArgs); } -llvm::DenormalMode -Linux::getDefaultDenormalModeForType(const llvm::opt::ArgList &DriverArgs, - const JobAction &JA, - const llvm::fltSemantics *FPType) const { - switch (getTriple().getArch()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: { - std::string Unused; - // DAZ and FTZ are turned on in crtfastmath.o - if (!DriverArgs.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && - isFastMathRuntimeAvailable(DriverArgs, Unused)) - return llvm::DenormalMode::getPreserveSign(); - return llvm::DenormalMode::getIEEE(); - } - default: - return llvm::DenormalMode::getIEEE(); - } -} - void Linux::addExtraOpts(llvm::opt::ArgStringList &CmdArgs) const { for (const auto &Opt : ExtraOpts) CmdArgs.push_back(Opt.c_str()); diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 524391743090..2d9e674e50a6 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -59,10 +59,6 @@ public: std::vector ExtraOpts; - llvm::DenormalMode getDefaultDenormalModeForType( - const llvm::opt::ArgList &DriverArgs, const JobAction &JA, - const llvm::fltSemantics *FPType = nullptr) const override; - const char *getDefaultLinker() const override; protected: diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp index 5a62c5deb240..96bef967d859 100644 --- a/clang/lib/ExtractAPI/API.cpp +++ b/clang/lib/ExtractAPI/API.cpp @@ -54,7 +54,28 @@ RecordContext *APIRecord::castToRecordContext(const APIRecord *Record) { } } +bool RecordContext::IsWellFormed() const { + // Check that First and Last are both null or both non-null. + return (First == nullptr) == (Last == nullptr); +} + +void RecordContext::stealRecordChain(RecordContext &Other) { + assert(IsWellFormed()); + // If we don't have an empty chain append Other's chain into ours. + if (First) + Last->NextInContext = Other.First; + else + First = Other.First; + + Last = Other.Last; + + // Delete Other's chain to ensure we don't accidentally traverse it. + Other.First = nullptr; + Other.Last = nullptr; +} + void RecordContext::addToRecordChain(APIRecord *Record) const { + assert(IsWellFormed()); if (!First) { First = Record; Last = Record; @@ -95,6 +116,7 @@ SymbolReference APISet::createSymbolReference(StringRef Name, StringRef USR, } APIRecord::~APIRecord() {} +TagRecord::~TagRecord() {} RecordRecord::~RecordRecord() {} RecordFieldRecord::~RecordFieldRecord() {} ObjCContainerRecord::~ObjCContainerRecord() {} diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 0a243120b7c0..9bf7950888db 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -396,7 +396,8 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( const TagDecl *Decl = TagTy->getDecl(); // Anonymous decl, skip this fragment. if (Decl->getName().empty()) - return Fragments; + return Fragments.append("{ ... }", + DeclarationFragments::FragmentKind::Text); SmallString<128> TagUSR; clang::index::generateUSRForDecl(Decl, TagUSR); return Fragments.append(Decl->getName(), @@ -743,11 +744,16 @@ DeclarationFragmentsBuilder::getFragmentsForEnum(const EnumDecl *EnumDecl) { QualType IntegerType = EnumDecl->getIntegerType(); if (!IntegerType.isNull()) - Fragments.append(": ", DeclarationFragments::FragmentKind::Text) + Fragments.appendSpace() + .append(": ", DeclarationFragments::FragmentKind::Text) .append( getFragmentsForType(IntegerType, EnumDecl->getASTContext(), After)) .append(std::move(After)); + if (EnumDecl->getName().empty()) + Fragments.appendSpace().append("{ ... }", + DeclarationFragments::FragmentKind::Text); + return Fragments.appendSemicolon(); } @@ -778,9 +784,12 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForRecordDecl( else Fragments.append("struct", DeclarationFragments::FragmentKind::Keyword); + Fragments.appendSpace(); if (!Record->getName().empty()) - Fragments.appendSpace().append( - Record->getName(), DeclarationFragments::FragmentKind::Identifier); + Fragments.append(Record->getName(), + DeclarationFragments::FragmentKind::Identifier); + else + Fragments.append("{ ... }", DeclarationFragments::FragmentKind::Text); return Fragments.appendSemicolon(); } diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 57f966c8b2be..34278b5d40c4 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -164,27 +164,29 @@ std::optional serializeAvailability(const AvailabilityInfo &Avail) { if (Avail.isDefault()) return std::nullopt; - Object Availability; Array AvailabilityArray; - Availability["domain"] = Avail.Domain; - serializeObject(Availability, "introduced", - serializeSemanticVersion(Avail.Introduced)); - serializeObject(Availability, "deprecated", - serializeSemanticVersion(Avail.Deprecated)); - serializeObject(Availability, "obsoleted", - serializeSemanticVersion(Avail.Obsoleted)); + if (Avail.isUnconditionallyDeprecated()) { Object UnconditionallyDeprecated; UnconditionallyDeprecated["domain"] = "*"; UnconditionallyDeprecated["isUnconditionallyDeprecated"] = true; AvailabilityArray.emplace_back(std::move(UnconditionallyDeprecated)); } - if (Avail.isUnconditionallyUnavailable()) { - Object UnconditionallyUnavailable; - UnconditionallyUnavailable["domain"] = "*"; - UnconditionallyUnavailable["isUnconditionallyUnavailable"] = true; - AvailabilityArray.emplace_back(std::move(UnconditionallyUnavailable)); + Object Availability; + + Availability["domain"] = Avail.Domain; + + if (Avail.isUnavailable()) { + Availability["isUnconditionallyUnavailable"] = true; + } else { + serializeObject(Availability, "introduced", + serializeSemanticVersion(Avail.Introduced)); + serializeObject(Availability, "deprecated", + serializeSemanticVersion(Avail.Deprecated)); + serializeObject(Availability, "obsoleted", + serializeSemanticVersion(Avail.Obsoleted)); } + AvailabilityArray.emplace_back(std::move(Availability)); return AvailabilityArray; } @@ -665,6 +667,14 @@ bool SymbolGraphSerializer::shouldSkip(const APIRecord *Record) const { if (Record->Availability.isUnconditionallyUnavailable()) return true; + // Filter out symbols without a name as we can generate correct symbol graphs + // for them. In practice these are anonymous record types that aren't attached + // to a declaration. + if (auto *Tag = dyn_cast(Record)) { + if (Tag->IsEmbeddedInVarDeclarator) + return true; + } + // Filter out symbols prefixed with an underscored as they are understood to // be symbols clients should not use. if (Record->Name.starts_with("_")) diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index ccb2c9190e2e..c8d8ec3afbd9 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -807,7 +807,6 @@ template <> struct MappingTraits { FormatStyle PredefinedStyle; if (getPredefinedStyle(StyleName, Style.Language, &PredefinedStyle) && Style == PredefinedStyle) { - IO.mapOptional("# BasedOnStyle", StyleName); BasedOnStyle = StyleName; break; } @@ -3117,6 +3116,7 @@ static void sortCppIncludes(const FormatStyle &Style, return; } + const auto OldCursor = Cursor ? *Cursor : 0; std::string result; for (unsigned Index : Indices) { if (!result.empty()) { @@ -3140,6 +3140,8 @@ static void sortCppIncludes(const FormatStyle &Style, // the entire range of blocks. Otherwise, no replacement is generated. if (replaceCRLF(result) == replaceCRLF(std::string(Code.substr( IncludesBeginOffset, IncludesBlockSize)))) { + if (Cursor) + *Cursor = OldCursor; return; } diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index f651e6228c20..28b6488e54a4 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -1623,10 +1623,10 @@ struct AdditionalKeywords { IdentifierInfo *kw_then; /// Returns \c true if \p Tok is a keyword or an identifier. - bool isWordLike(const FormatToken &Tok) const { + bool isWordLike(const FormatToken &Tok, bool IsVerilog = true) const { // getIdentifierinfo returns non-null for keywords as well as identifiers. return Tok.Tok.getIdentifierInfo() && - !Tok.isOneOf(kw_verilogHash, kw_verilogHashHash, kw_apostrophe); + (!IsVerilog || !isVerilogKeywordSymbol(Tok)); } /// Returns \c true if \p Tok is a true JavaScript identifier, returns @@ -1755,6 +1755,10 @@ struct AdditionalKeywords { } } + bool isVerilogKeywordSymbol(const FormatToken &Tok) const { + return Tok.isOneOf(kw_verilogHash, kw_verilogHashHash, kw_apostrophe); + } + bool isVerilogWordOperator(const FormatToken &Tok) const { return Tok.isOneOf(kw_before, kw_intersect, kw_dist, kw_iff, kw_inside, kw_with); diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index cdfb4256e41d..d366ae2080bc 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -4780,9 +4780,14 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Left.Finalized) return Right.hasWhitespaceBefore(); + const bool IsVerilog = Style.isVerilog(); + assert(!IsVerilog || !IsCpp); + // Never ever merge two words. - if (Keywords.isWordLike(Right) && Keywords.isWordLike(Left)) + if (Keywords.isWordLike(Right, IsVerilog) && + Keywords.isWordLike(Left, IsVerilog)) { return true; + } // Leave a space between * and /* to avoid C4138 `comment end` found outside // of comment. @@ -4834,10 +4839,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Right.is(TT_TemplateOpener)) { return true; } - if (Left.is(tok::identifier) && Right.is(tok::numeric_constant) && - Right.TokenText[0] == '.') { - return false; - } + if (Left.Tok.getIdentifierInfo() && Right.is(tok::numeric_constant)) + return Right.TokenText[0] != '.'; } else if (Style.isProto()) { if (Right.is(tok::period) && Left.isOneOf(Keywords.kw_optional, Keywords.kw_required, @@ -5065,12 +5068,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, Right.is(TT_TemplateOpener)) { return true; } - } else if (Style.isVerilog()) { + } else if (IsVerilog) { // An escaped identifier ends with whitespace. - if (Style.isVerilog() && Left.is(tok::identifier) && - Left.TokenText[0] == '\\') { + if (Left.is(tok::identifier) && Left.TokenText[0] == '\\') return true; - } // Add space between things in a primitive's state table unless in a // transition like `(0?)`. if ((Left.is(TT_VerilogTableItem) && @@ -5266,21 +5267,11 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, return true; } if (Left.is(TT_UnaryOperator)) { - if (Right.isNot(tok::l_paren)) { - // The alternative operators for ~ and ! are "compl" and "not". - // If they are used instead, we do not want to combine them with - // the token to the right, unless that is a left paren. - if (Left.is(tok::exclaim) && Left.TokenText == "not") - return true; - if (Left.is(tok::tilde) && Left.TokenText == "compl") - return true; - // Lambda captures allow for a lone &, so "&]" needs to be properly - // handled. - if (Left.is(tok::amp) && Right.is(tok::r_square)) - return Style.SpacesInSquareBrackets; - } - return (Style.SpaceAfterLogicalNot && Left.is(tok::exclaim)) || - Right.is(TT_BinaryOperator); + // Lambda captures allow for a lone &, so "&]" needs to be properly + // handled. + if (Left.is(tok::amp) && Right.is(tok::r_square)) + return Style.SpacesInSquareBrackets; + return Style.SpaceAfterLogicalNot && Left.is(tok::exclaim); } // If the next token is a binary operator or a selector name, we have diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 603268f771ac..3a263955a6a8 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -534,11 +534,11 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { case tok::r_brace: if (LBraceStack.empty()) break; - if (LBraceStack.back().Tok->is(BK_Unknown)) { + if (auto *LBrace = LBraceStack.back().Tok; LBrace->is(BK_Unknown)) { bool ProbablyBracedList = false; if (Style.Language == FormatStyle::LK_Proto) { ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square); - } else { + } else if (LBrace->isNot(TT_EnumLBrace)) { // Using OriginalColumn to distinguish between ObjC methods and // binary operators is a bit hacky. bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) && @@ -552,7 +552,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { // If we already marked the opening brace as braced list, the closing // must also be part of it. - ProbablyBracedList = LBraceStack.back().Tok->is(TT_BracedListLBrace); + ProbablyBracedList = LBrace->is(TT_BracedListLBrace); ProbablyBracedList = ProbablyBracedList || (Style.isJavaScript() && @@ -608,13 +608,9 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { ProbablyBracedList = true; } } - if (ProbablyBracedList) { - Tok->setBlockKind(BK_BracedInit); - LBraceStack.back().Tok->setBlockKind(BK_BracedInit); - } else { - Tok->setBlockKind(BK_Block); - LBraceStack.back().Tok->setBlockKind(BK_Block); - } + const auto BlockKind = ProbablyBracedList ? BK_BracedInit : BK_Block; + Tok->setBlockKind(BlockKind); + LBrace->setBlockKind(BlockKind); } LBraceStack.pop_back(); break; @@ -819,8 +815,11 @@ FormatToken *UnwrappedLineParser::parseBlock(bool MustBeDeclaration, return IfLBrace; } - if (FormatTok->is(tok::r_brace) && Tok->is(TT_NamespaceLBrace)) - FormatTok->setFinalizedType(TT_NamespaceRBrace); + if (FormatTok->is(tok::r_brace)) { + FormatTok->setBlockKind(BK_Block); + if (Tok->is(TT_NamespaceLBrace)) + FormatTok->setFinalizedType(TT_NamespaceRBrace); + } const bool IsFunctionRBrace = FormatTok->is(tok::r_brace) && Tok->is(TT_FunctionLBrace); @@ -2415,6 +2414,7 @@ bool UnwrappedLineParser::tryToParseChildBlock() { } bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { + assert(!IsAngleBracket || !IsEnum); bool HasError = false; // FIXME: Once we have an expression parser in the UnwrappedLineParser, @@ -2437,8 +2437,11 @@ bool UnwrappedLineParser::parseBracedList(bool IsAngleBracket, bool IsEnum) { } } if (FormatTok->is(IsAngleBracket ? tok::greater : tok::r_brace)) { - if (IsEnum && !Style.AllowShortEnumsOnASingleLine) - addUnwrappedLine(); + if (IsEnum) { + FormatTok->setBlockKind(BK_Block); + if (!Style.AllowShortEnumsOnASingleLine) + addUnwrappedLine(); + } nextToken(); return !HasError; } @@ -3910,6 +3913,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { const FormatToken &InitialToken = *FormatTok; nextToken(); + const FormatToken *ClassName = nullptr; + bool IsDerived = false; auto IsNonMacroIdentifier = [](const FormatToken *Tok) { return Tok->is(tok::identifier) && Tok->TokenText != Tok->TokenText.upper(); }; @@ -3934,15 +3939,35 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } if (FormatTok->is(tok::l_square) && handleCppAttributes()) continue; + const auto *Previous = FormatTok; nextToken(); - // We can have macros in between 'class' and the class name. - if (!IsNonMacroIdentifier(FormatTok->Previous) && - FormatTok->is(tok::l_paren)) { - parseParens(); + switch (FormatTok->Tok.getKind()) { + case tok::l_paren: + // We can have macros in between 'class' and the class name. + if (!IsNonMacroIdentifier(Previous)) + parseParens(); + break; + case tok::coloncolon: + break; + default: + if (!ClassName && Previous->is(tok::identifier)) + ClassName = Previous; } } + auto IsListInitialization = [&] { + if (!ClassName || IsDerived) + return false; + assert(FormatTok->is(tok::l_brace)); + const auto *Prev = FormatTok->getPreviousNonComment(); + assert(Prev); + return Prev != ClassName && Prev->is(tok::identifier) && + Prev->isNot(Keywords.kw_final) && tryToParseBracedList(); + }; + if (FormatTok->isOneOf(tok::colon, tok::less)) { + if (FormatTok->is(tok::colon)) + IsDerived = true; int AngleNestingLevel = 0; do { if (FormatTok->is(tok::less)) @@ -3955,6 +3980,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { break; } if (FormatTok->is(tok::l_brace)) { + if (AngleNestingLevel == 0 && IsListInitialization()) + return; calculateBraceTypes(/*ExpectClassBody=*/true); if (!tryToParseBracedList()) break; @@ -3999,6 +4026,8 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) { } }; if (FormatTok->is(tok::l_brace)) { + if (IsListInitialization()) + return; auto [OpenBraceType, ClosingBraceType] = GetBraceTypes(InitialToken); FormatTok->setFinalizedType(OpenBraceType); if (ParseAsExpr) { diff --git a/clang/lib/Format/WhitespaceManager.cpp b/clang/lib/Format/WhitespaceManager.cpp index 4f822807dd98..44fd807ec27e 100644 --- a/clang/lib/Format/WhitespaceManager.cpp +++ b/clang/lib/Format/WhitespaceManager.cpp @@ -128,11 +128,14 @@ const tooling::Replacements &WhitespaceManager::generateReplacements() { void WhitespaceManager::calculateLineBreakInformation() { Changes[0].PreviousEndOfTokenColumn = 0; Change *LastOutsideTokenChange = &Changes[0]; - for (unsigned i = 1, e = Changes.size(); i != e; ++i) { + for (unsigned I = 1, e = Changes.size(); I != e; ++I) { + auto &C = Changes[I]; + auto &P = Changes[I - 1]; + auto &PrevTokLength = P.TokenLength; SourceLocation OriginalWhitespaceStart = - Changes[i].OriginalWhitespaceRange.getBegin(); + C.OriginalWhitespaceRange.getBegin(); SourceLocation PreviousOriginalWhitespaceEnd = - Changes[i - 1].OriginalWhitespaceRange.getEnd(); + P.OriginalWhitespaceRange.getEnd(); unsigned OriginalWhitespaceStartOffset = SourceMgr.getFileOffset(OriginalWhitespaceStart); unsigned PreviousOriginalWhitespaceEndOffset = @@ -167,31 +170,28 @@ void WhitespaceManager::calculateLineBreakInformation() { // line of the token. auto NewlinePos = Text.find_first_of('\n'); if (NewlinePos == StringRef::npos) { - Changes[i - 1].TokenLength = OriginalWhitespaceStartOffset - - PreviousOriginalWhitespaceEndOffset + - Changes[i].PreviousLinePostfix.size() + - Changes[i - 1].CurrentLinePrefix.size(); + PrevTokLength = OriginalWhitespaceStartOffset - + PreviousOriginalWhitespaceEndOffset + + C.PreviousLinePostfix.size() + P.CurrentLinePrefix.size(); + if (!P.IsInsideToken) + PrevTokLength = std::min(PrevTokLength, P.Tok->ColumnWidth); } else { - Changes[i - 1].TokenLength = - NewlinePos + Changes[i - 1].CurrentLinePrefix.size(); + PrevTokLength = NewlinePos + P.CurrentLinePrefix.size(); } // If there are multiple changes in this token, sum up all the changes until // the end of the line. - if (Changes[i - 1].IsInsideToken && Changes[i - 1].NewlinesBefore == 0) { - LastOutsideTokenChange->TokenLength += - Changes[i - 1].TokenLength + Changes[i - 1].Spaces; - } else { - LastOutsideTokenChange = &Changes[i - 1]; - } + if (P.IsInsideToken && P.NewlinesBefore == 0) + LastOutsideTokenChange->TokenLength += PrevTokLength + P.Spaces; + else + LastOutsideTokenChange = &P; - Changes[i].PreviousEndOfTokenColumn = - Changes[i - 1].StartOfTokenColumn + Changes[i - 1].TokenLength; + C.PreviousEndOfTokenColumn = P.StartOfTokenColumn + PrevTokLength; - Changes[i - 1].IsTrailingComment = - (Changes[i].NewlinesBefore > 0 || Changes[i].Tok->is(tok::eof) || - (Changes[i].IsInsideToken && Changes[i].Tok->is(tok::comment))) && - Changes[i - 1].Tok->is(tok::comment) && + P.IsTrailingComment = + (C.NewlinesBefore > 0 || C.Tok->is(tok::eof) || + (C.IsInsideToken && C.Tok->is(tok::comment))) && + P.Tok->is(tok::comment) && // FIXME: This is a dirty hack. The problem is that // BreakableLineCommentSection does comment reflow changes and here is // the aligning of trailing comments. Consider the case where we reflow diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 3610a08831e7..1b93588553a2 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -1067,7 +1067,7 @@ public: std::vector takeTopLevelDecls() { return std::move(TopLevelDecls); } - std::vector takeTopLevelDeclIDs() { + std::vector takeTopLevelDeclIDs() { return std::move(TopLevelDeclIDs); } @@ -1101,7 +1101,7 @@ public: private: unsigned Hash = 0; std::vector TopLevelDecls; - std::vector TopLevelDeclIDs; + std::vector TopLevelDeclIDs; llvm::SmallVector PreambleDiags; }; @@ -1467,11 +1467,12 @@ void ASTUnit::RealizeTopLevelDeclsFromPreamble() { std::vector Resolved; Resolved.reserve(TopLevelDeclsInPreamble.size()); - ExternalASTSource &Source = *getASTContext().getExternalSource(); + // The module file of the preamble. + serialization::ModuleFile &MF = Reader->getModuleManager().getPrimaryModule(); for (const auto TopLevelDecl : TopLevelDeclsInPreamble) { // Resolve the declaration ID to an actual declaration, possibly // deserializing the declaration in the process. - if (Decl *D = Source.GetExternalDecl(TopLevelDecl)) + if (Decl *D = Reader->GetDecl(Reader->getGlobalDeclID(MF, TopLevelDecl))) Resolved.push_back(D); } TopLevelDeclsInPreamble.clear(); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 6e3baf838644..66a45b888f15 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -1293,6 +1293,10 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc, diag::remark_module_build_done) << ModuleName; + // Propagate the statistics to the parent FileManager. + if (!FrontendOpts.ModulesShareFileManager) + ImportingInstance.getFileManager().AddStats(Instance.getFileManager()); + if (Crashed) { // Clear the ASTConsumer if it hasn't been already, in case it owns streams // that must be closed before clearing output files. diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index b7c9967316f0..9ae7664b4b49 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -80,7 +80,7 @@ public: if (Previous) Previous->TypeRead(Idx, T); } - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (Previous) Previous->DeclRead(ID, D); } @@ -102,7 +102,7 @@ public: bool DeletePrevious) : DelegatingDeserializationListener(Previous, DeletePrevious) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { llvm::outs() << "PCH DECL: " << D->getDeclKindName(); if (const NamedDecl *ND = dyn_cast(D)) { llvm::outs() << " - "; @@ -128,7 +128,7 @@ public: : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx), NamesToCheck(NamesToCheck) {} - void DeclRead(serialization::DeclID ID, const Decl *D) override { + void DeclRead(GlobalDeclID ID, const Decl *D) override { if (const NamedDecl *ND = dyn_cast(D)) if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) { unsigned DiagID @@ -757,8 +757,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // IR files bypass the rest of initialization. if (Input.getKind().getLanguage() == Language::LLVM_IR) { - assert(hasIRSupport() && - "This action does not have IR file support!"); + if (!hasIRSupport()) { + CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir) + << Input.getFile(); + return false; + } // Inform the diagnostic client we are processing a source file. CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 4f44c3b7b89d..c1d209466ffe 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -389,8 +389,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, Twine((unsigned)LangOpts.getHLSLVersion())); if (LangOpts.NativeHalfType) - Builder.defineMacro("__HLSL_ENABLE_16_BIT", - Twine((unsigned)LangOpts.getHLSLVersion())); + Builder.defineMacro("__HLSL_ENABLE_16_BIT", "1"); // Shader target information // "enums" for shader stages @@ -704,7 +703,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_nested_namespace_definitions", "201411L"); Builder.defineMacro("__cpp_variadic_using", "201611L"); Builder.defineMacro("__cpp_aggregate_bases", "201603L"); - Builder.defineMacro("__cpp_structured_bindings", "201606L"); + Builder.defineMacro("__cpp_structured_bindings", "202403L"); Builder.defineMacro("__cpp_nontype_template_args", "201411L"); // (not latest) Builder.defineMacro("__cpp_fold_expressions", "201603L"); @@ -1309,6 +1308,16 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1"); } + // GCC defines these macros in both C and C++ modes despite them being needed + // mostly for STL implementations in C++. + auto [Destructive, Constructive] = TI.hardwareInterferenceSizes(); + Builder.defineMacro("__GCC_DESTRUCTIVE_SIZE", Twine(Destructive)); + Builder.defineMacro("__GCC_CONSTRUCTIVE_SIZE", Twine(Constructive)); + // We need to use push_macro to allow users to redefine these macros from the + // command line with -D and not issue a -Wmacro-redefined warning. + Builder.append("#pragma push_macro(\"__GCC_DESTRUCTIVE_SIZE\")"); + Builder.append("#pragma push_macro(\"__GCC_CONSTRUCTIVE_SIZE\")"); + auto addLockFreeMacros = [&](const llvm::Twine &Prefix) { // Used by libc++ and libstdc++ to implement ATOMIC__LOCK_FREE. #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \ diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index 744ea70cc24d..c74bfd86195f 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -52,8 +52,8 @@ void MultiplexASTDeserializationListener::TypeRead( Listeners[i]->TypeRead(Idx, T); } -void MultiplexASTDeserializationListener::DeclRead( - serialization::DeclID ID, const Decl *D) { +void MultiplexASTDeserializationListener::DeclRead(GlobalDeclID ID, + const Decl *D) { for (size_t i = 0, e = Listeners.size(); i != e; ++i) Listeners[i]->DeclRead(ID, D); } diff --git a/clang/lib/Headers/cpuid.h b/clang/lib/Headers/cpuid.h index 0bb9912b465f..bb7692efb78f 100644 --- a/clang/lib/Headers/cpuid.h +++ b/clang/lib/Headers/cpuid.h @@ -10,7 +10,7 @@ #ifndef __CPUID_H #define __CPUID_H -#if !(__x86_64__ || __i386__) +#if !defined(__x86_64__) && !defined(__i386__) #error this header is for x86 only #endif @@ -256,7 +256,7 @@ #define bit_AVX10_256 0x00020000 #define bit_AVX10_512 0x00040000 -#if __i386__ +#ifdef __i386__ #define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \ __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ : "0"(__leaf)) @@ -285,7 +285,7 @@ static __inline unsigned int __get_cpuid_max (unsigned int __leaf, unsigned int *__sig) { unsigned int __eax, __ebx, __ecx, __edx; -#if __i386__ +#ifdef __i386__ int __cpuid_supported; __asm(" pushfl\n" diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp index 0632882b2961..574723b33866 100644 --- a/clang/lib/Lex/HeaderSearch.cpp +++ b/clang/lib/Lex/HeaderSearch.cpp @@ -1574,6 +1574,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP, } } + FileInfo.IsLocallyIncluded = true; IsFirstIncludeOfFile = PP.markIncluded(File); return true; } diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index d054eda279b8..a26568dfd6aa 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -603,6 +603,8 @@ void Parser::ParseLexedMethodDef(LexedMethod &LM) { // to be re-used for method bodies as well. ParseScope FnScope(this, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D); if (Tok.is(tok::kw_try)) { diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 5f26b5a9e46b..a7846e102a43 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2222,7 +2222,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, } if (getLangOpts().HLSL) - MaybeParseHLSLSemantics(D); + MaybeParseHLSLAnnotations(D); if (Tok.is(tok::kw_requires)) ParseTrailingRequiresClause(D); @@ -2469,7 +2469,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, ParseDeclarator(D); if (getLangOpts().HLSL) - MaybeParseHLSLSemantics(D); + MaybeParseHLSLAnnotations(D); if (!D.isInvalidType()) { // C++2a [dcl.decl]p1 @@ -7038,18 +7038,23 @@ void Parser::ParseDirectDeclarator(Declarator &D) { void Parser::ParseDecompositionDeclarator(Declarator &D) { assert(Tok.is(tok::l_square)); + TentativeParsingAction PA(*this); + BalancedDelimiterTracker T(*this, tok::l_square); + T.consumeOpen(); + + if (isCXX11AttributeSpecifier()) + DiagnoseAndSkipCXX11Attributes(); + // If this doesn't look like a structured binding, maybe it's a misplaced // array declarator. - // FIXME: Consume the l_square first so we don't need extra lookahead for - // this. - if (!(NextToken().is(tok::identifier) && - GetLookAheadToken(2).isOneOf(tok::comma, tok::r_square)) && - !(NextToken().is(tok::r_square) && - GetLookAheadToken(2).isOneOf(tok::equal, tok::l_brace))) + if (!(Tok.is(tok::identifier) && + NextToken().isOneOf(tok::comma, tok::r_square, tok::kw_alignas, + tok::l_square)) && + !(Tok.is(tok::r_square) && + NextToken().isOneOf(tok::equal, tok::l_brace))) { + PA.Revert(); return ParseMisplacedBracketDeclarator(D); - - BalancedDelimiterTracker T(*this, tok::l_square); - T.consumeOpen(); + } SmallVector Bindings; while (Tok.isNot(tok::r_square)) { @@ -7074,13 +7079,27 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { } } + if (isCXX11AttributeSpecifier()) + DiagnoseAndSkipCXX11Attributes(); + if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected) << tok::identifier; break; } - Bindings.push_back({Tok.getIdentifierInfo(), Tok.getLocation()}); + IdentifierInfo *II = Tok.getIdentifierInfo(); + SourceLocation Loc = Tok.getLocation(); ConsumeToken(); + + ParsedAttributes Attrs(AttrFactory); + if (isCXX11AttributeSpecifier()) { + Diag(Tok, getLangOpts().CPlusPlus26 + ? diag::warn_cxx23_compat_decl_attrs_on_binding + : diag::ext_decl_attrs_on_binding); + MaybeParseCXX11Attributes(Attrs); + } + + Bindings.push_back({II, Loc, std::move(Attrs)}); } if (Tok.isNot(tok::r_square)) @@ -7095,6 +7114,8 @@ void Parser::ParseDecompositionDeclarator(Declarator &D) { T.consumeClose(); } + PA.Commit(); + return D.setDecompositionBindings(T.getOpenLocation(), Bindings, T.getCloseLocation()); } @@ -7699,7 +7720,7 @@ void Parser::ParseParameterDeclarationClause( // Parse GNU attributes, if present. MaybeParseGNUAttributes(ParmDeclarator); if (getLangOpts().HLSL) - MaybeParseHLSLSemantics(DS.getAttributes()); + MaybeParseHLSLAnnotations(DS.getAttributes()); if (Tok.is(tok::kw_requires)) { // User tried to define a requires clause in a parameter declaration, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 32d96f81c4c8..7d6febb04a82 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -31,6 +31,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/SemaCUDA.h" +#include "clang/Sema/SemaOpenACC.h" #include "clang/Sema/SemaOpenMP.h" #include "clang/Sema/SemaSYCL.h" #include "clang/Sema/TypoCorrection.h" @@ -2070,15 +2071,22 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { if (!LHS.isInvalid() && !HasError && !Length.isInvalid() && !Stride.isInvalid() && Tok.is(tok::r_square)) { if (ColonLocFirst.isValid() || ColonLocSecond.isValid()) { - // FIXME: OpenACC hasn't implemented Sema/Array section handling at a - // semantic level yet. For now, just reuse the OpenMP implementation - // as it gets the parsing/type management mostly right, and we can - // replace this call to ActOnOpenACCArraySectionExpr in the future. - // Eventually we'll genericize the OPenMPArraySectionExpr type as - // well. - LHS = Actions.OpenMP().ActOnOMPArraySectionExpr( - LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], - ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), RLoc); + // Like above, AllowOpenACCArraySections is 'more specific' and only + // enabled when actively parsing a 'var' in a 'var-list' during + // clause/'cache' construct parsing, so it is more specific. So we + // should do it first, so that the correct node gets created. + if (AllowOpenACCArraySections) { + assert(!Stride.isUsable() && !ColonLocSecond.isValid() && + "Stride/second colon not allowed for OpenACC"); + LHS = Actions.OpenACC().ActOnArraySectionExpr( + LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], + ColonLocFirst, Length.get(), RLoc); + } else { + LHS = Actions.OpenMP().ActOnOMPArraySectionExpr( + LHS.get(), Loc, ArgExprs.empty() ? nullptr : ArgExprs[0], + ColonLocFirst, ColonLocSecond, Length.get(), Stride.get(), + RLoc); + } } else { LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.get(), Loc, ArgExprs, RLoc); diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp index d97985d42369..f4cbece31f18 100644 --- a/clang/lib/Parse/ParseHLSL.cpp +++ b/clang/lib/Parse/ParseHLSL.cpp @@ -63,7 +63,7 @@ Decl *Parser::ParseHLSLBuffer(SourceLocation &DeclEnd) { SourceLocation IdentifierLoc = ConsumeToken(); ParsedAttributes Attrs(AttrFactory); - MaybeParseHLSLSemantics(Attrs, nullptr); + MaybeParseHLSLAnnotations(Attrs, nullptr); ParseScope BufferScope(this, Scope::DeclScope); BalancedDelimiterTracker T(*this, tok::l_brace); @@ -118,12 +118,10 @@ static void fixSeparateAttrArgAndNumber(StringRef ArgStr, SourceLocation ArgLoc, Slot = IdentifierLoc::create(Ctx, ArgLoc, PP.getIdentifierInfo(FixedArg)); } -void Parser::ParseHLSLSemantics(ParsedAttributes &Attrs, - SourceLocation *EndLoc) { - // FIXME: HLSLSemantic is shared for Semantic and resource binding which is - // confusing. Need a better name to avoid misunderstanding. Issue - // https://github.com/llvm/llvm-project/issues/57882 - assert(Tok.is(tok::colon) && "Not a HLSL Semantic"); +void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs, + SourceLocation *EndLoc) { + + assert(Tok.is(tok::colon) && "Not a HLSL Annotation"); ConsumeToken(); IdentifierInfo *II = nullptr; @@ -141,7 +139,7 @@ void Parser::ParseHLSLSemantics(ParsedAttributes &Attrs, if (EndLoc) *EndLoc = Tok.getLocation(); ParsedAttr::Kind AttrKind = - ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLSemantic); + ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation); ArgsVector ArgExprs; switch (AttrKind) { @@ -192,10 +190,10 @@ void Parser::ParseHLSLSemantics(ParsedAttributes &Attrs, case ParsedAttr::AT_HLSLSV_DispatchThreadID: break; default: - llvm_unreachable("invalid HLSL Semantic"); + llvm_unreachable("invalid HLSL Annotation"); break; } Attrs.addNew(II, Loc, nullptr, SourceLocation(), ArgExprs.data(), - ArgExprs.size(), ParsedAttr::Form::HLSLSemantic()); + ArgExprs.size(), ParsedAttr::Form::HLSLAnnotation()); } diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 671dcb71e51a..8e54fe012c55 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -3736,6 +3736,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) { ParseScope BodyScope(this, (parseMethod ? Scope::ObjCMethodScope : 0) | Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope); + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); // Tell the actions module that we have entered a method or c-function definition // with the specified Declarator for the method/function. diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index 8a18fca8064e..29326f5d993a 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -327,7 +327,7 @@ OpenACCReductionOperator ParseReductionOperator(Parser &P) { return OpenACCReductionOperator::Max; if (ReductionKindTok.getIdentifierInfo()->isStr("min")) return OpenACCReductionOperator::Min; - LLVM_FALLTHROUGH; + [[fallthrough]]; default: P.Diag(ReductionKindTok, diag::err_acc_invalid_reduction_operator); return OpenACCReductionOperator::Invalid; @@ -945,7 +945,7 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( // the 'update' clause, so we have to handle it here. U se an assert to // make sure we get the right differentiator. assert(DirKind == OpenACCDirectiveKind::Update); - LLVM_FALLTHROUGH; + [[fallthrough]]; case OpenACCClauseKind::Attach: case OpenACCClauseKind::Copy: case OpenACCClauseKind::Delete: diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index b07ce451e878..665253a6674d 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -733,7 +733,12 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { // we introduce the type parameter into the local scope. SourceLocation EqualLoc; ParsedType DefaultArg; + std::optional DontDestructTemplateIds; if (TryConsumeToken(tok::equal, EqualLoc)) { + // The default argument might contain a lambda declaration; avoid destroying + // parsed template ids at the end of that declaration because they can be + // used in a type constraint later. + DontDestructTemplateIds.emplace(*this, /*DelayTemplateIdDestruction=*/true); // The default argument may declare template parameters, notably // if it contains a generic lambda, so we need to increase // the template depth as these parameters would not be instantiated diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index ef46fc74cedc..adcbe5858bc7 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1497,6 +1497,8 @@ Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, return Actions.ActOnFinishFunctionBody(Res, nullptr, false); } + Sema::FPFeaturesStateRAII SaveFPFeatures(Actions); + if (Tok.is(tok::kw_try)) return ParseFunctionTryBlock(Res, BodyScope); diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index b79683bb32a6..5f63c857c430 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -293,7 +293,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, void Declarator::setDecompositionBindings( SourceLocation LSquareLoc, - ArrayRef Bindings, + MutableArrayRef Bindings, SourceLocation RSquareLoc) { assert(!hasName() && "declarator given multiple names!"); @@ -317,7 +317,7 @@ void Declarator::setDecompositionBindings( new DecompositionDeclarator::Binding[Bindings.size()]; BindingGroup.DeleteBindings = true; } - std::uninitialized_copy(Bindings.begin(), Bindings.end(), + std::uninitialized_move(Bindings.begin(), Bindings.end(), BindingGroup.Bindings); } } diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index ce6211c23218..8af36d5c24e3 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -180,7 +180,8 @@ static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) { } const Expr *Init = VD->getInit(); - if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init) { + if (S.Context.getLangOpts().CPlusPlus && VD->hasLocalStorage() && Init && + !Init->containsErrors()) { // C++11 [stmt.dcl]p3: // A program that jumps from a point where a variable with automatic // storage duration is not in scope to a point where it is in scope diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index 058e22cb2b81..79e656eb4b7e 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -46,7 +46,7 @@ void MultiplexExternalSemaSource::AddSource(ExternalSemaSource *Source) { // ExternalASTSource. //===----------------------------------------------------------------------===// -Decl *MultiplexExternalSemaSource::GetExternalDecl(uint32_t ID) { +Decl *MultiplexExternalSemaSource::GetExternalDecl(GlobalDeclID ID) { for(size_t i = 0; i < Sources.size(); ++i) if (Decl *Result = Sources[i]->GetExternalDecl(ID)) return Result; diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 4c445f28bba8..c5998aca0d72 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -594,6 +594,11 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info, D->addAttr( SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value())); + if (auto Copyable = Info.isSwiftCopyable()) { + if (!*Copyable) + D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable")); + } + if (auto Extensibility = Info.EnumExtensibility) { using api_notes::EnumExtensibilityKind; bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 51757f4cf727..cf8840c63024 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3164,13 +3164,20 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, const Expr *Arg = TheCall->getArg(0); const auto *TyA = Arg->getType()->getAs(); - if (!TyA) { + + QualType ElTy; + if (TyA) + ElTy = TyA->getElementType(); + else if (Arg->getType()->isSizelessVectorType()) + ElTy = Arg->getType()->getSizelessVectorEltType(Context); + + if (ElTy.isNull()) { Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) << 1 << /* vector ty*/ 4 << Arg->getType(); return ExprError(); } - TheCall->setType(TyA->getElementType()); + TheCall->setType(ElTy); break; } @@ -3186,12 +3193,20 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, const Expr *Arg = TheCall->getArg(0); const auto *TyA = Arg->getType()->getAs(); - if (!TyA || !TyA->getElementType()->isIntegerType()) { + + QualType ElTy; + if (TyA) + ElTy = TyA->getElementType(); + else if (Arg->getType()->isSizelessVectorType()) + ElTy = Arg->getType()->getSizelessVectorEltType(Context); + + if (ElTy.isNull() || !ElTy->isIntegerType()) { Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type) << 1 << /* vector of integers */ 6 << Arg->getType(); return ExprError(); } - TheCall->setType(TyA->getElementType()); + + TheCall->setType(ElTy); break; } @@ -7953,7 +7968,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, // For variadic functions, we may have more args than parameters. // For some K&R functions, we may have less args than parameters. const auto N = std::min(Proto->getNumParams(), Args.size()); - bool AnyScalableArgsOrRet = Proto->getReturnType()->isSizelessVectorType(); + bool IsScalableRet = Proto->getReturnType()->isSizelessVectorType(); + bool IsScalableArg = false; for (unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) { // Args[ArgIdx] can be null in malformed code. if (const Expr *Arg = Args[ArgIdx]) { @@ -7968,7 +7984,7 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, QualType ParamTy = Proto->getParamType(ArgIdx); if (ParamTy->isSizelessVectorType()) - AnyScalableArgsOrRet = true; + IsScalableArg = true; QualType ArgTy = Arg->getType(); CheckArgAlignment(Arg->getExprLoc(), FDecl, std::to_string(ArgIdx + 1), ArgTy, ParamTy); @@ -7993,7 +8009,8 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, // arguments or return values, then warn the user that the streaming and // non-streaming vector lengths may be different. const auto *CallerFD = dyn_cast(CurContext); - if (CallerFD && (!FD || !FD->getBuiltinID()) && AnyScalableArgsOrRet) { + if (CallerFD && (!FD || !FD->getBuiltinID()) && + (IsScalableArg || IsScalableRet)) { bool IsCalleeStreaming = ExtInfo.AArch64SMEAttributes & FunctionType::SME_PStateSMEnabledMask; bool IsCalleeStreamingCompatible = @@ -8002,8 +8019,14 @@ void Sema::checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, ArmStreamingType CallerFnType = getArmStreamingFnType(CallerFD); if (!IsCalleeStreamingCompatible && (CallerFnType == ArmStreamingCompatible || - ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming))) - Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming); + ((CallerFnType == ArmStreaming) ^ IsCalleeStreaming))) { + if (IsScalableArg) + Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) + << /*IsArg=*/true; + if (IsScalableRet) + Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming) + << /*IsArg=*/false; + } } FunctionType::ArmStateValue CalleeArmZAState = @@ -12536,6 +12559,17 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, return true; } + // Diagnose attempts to use '%P' with ObjC object types, which will result in + // dumping raw class data (like is-a pointer), not actual data. + if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg && + ExprTy->isObjCObjectPointerType()) { + const CharSourceRange &CSR = + getSpecifierRange(StartSpecifier, SpecifierLen); + EmitFormatDiagnostic(S.PDiag(diag::warn_format_P_with_objc_pointer), + E->getExprLoc(), false, CSR); + return true; + } + ArgType::MatchKind ImplicitMatch = ArgType::NoMatch; ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy); ArgType::MatchKind OrigMatch = Match; @@ -18716,8 +18750,10 @@ void Sema::CheckArrayAccess(const Expr *expr) { expr = cast(expr)->getBase(); break; } - case Stmt::OMPArraySectionExprClass: { - const OMPArraySectionExpr *ASE = cast(expr); + case Stmt::ArraySectionExprClass: { + const ArraySectionExpr *ASE = cast(expr); + // FIXME: We should probably be checking all of the elements to the + // 'length' here as well. if (ASE->getLowerBound()) CheckArrayAccess(ASE->getBase(), ASE->getLowerBound(), /*ASE=*/nullptr, AllowOnePastEnd > 0); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 35eac93e324d..671752b56e01 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1974,7 +1974,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts, // it is, by the bindings' expressions). bool IsAllPlaceholders = true; for (const auto *BD : DD->bindings()) { - if (BD->isReferenced()) + if (BD->isReferenced() || BD->hasAttr()) return false; IsAllPlaceholders = IsAllPlaceholders && BD->isPlaceholderVar(LangOpts); } @@ -12417,12 +12417,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, bool UsesZT0 = Attr && Attr->isNewZT0(); if (NewFD->hasAttr()) { - if (NewFD->getReturnType()->isSizelessVectorType() || - llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) { + if (NewFD->getReturnType()->isSizelessVectorType()) + Diag(NewFD->getLocation(), + diag::warn_sme_locally_streaming_has_vl_args_returns) + << /*IsArg=*/false; + if (llvm::any_of(NewFD->parameters(), [](ParmVarDecl *P) { return P->getOriginalType()->isSizelessVectorType(); })) Diag(NewFD->getLocation(), - diag::warn_sme_locally_streaming_has_vl_args_returns); + diag::warn_sme_locally_streaming_has_vl_args_returns) + << /*IsArg=*/true; } if (const auto *FPT = NewFD->getType()->getAs()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); @@ -13498,16 +13502,18 @@ void Sema::checkNonTrivialCUnion(QualType QT, SourceLocation Loc, void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. - if (!RealDecl || RealDecl->isInvalidDecl()) { + if (!RealDecl) { CorrectDelayedTyposInExpr(Init, dyn_cast_or_null(RealDecl)); return; } - if (CXXMethodDecl *Method = dyn_cast(RealDecl)) { - // Pure-specifiers are handled in ActOnPureSpecifier. - Diag(Method->getLocation(), diag::err_member_function_initialization) - << Method->getDeclName() << Init->getSourceRange(); - Method->setInvalidDecl(); + if (auto *Method = dyn_cast(RealDecl)) { + if (!Method->isInvalidDecl()) { + // Pure-specifiers are handled in ActOnPureSpecifier. + Diag(Method->getLocation(), diag::err_member_function_initialization) + << Method->getDeclName() << Init->getSourceRange(); + Method->setInvalidDecl(); + } return; } @@ -13519,6 +13525,15 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { return; } + if (VDecl->isInvalidDecl()) { + CorrectDelayedTyposInExpr(Init, VDecl); + ExprResult Recovery = + CreateRecoveryExpr(Init->getBeginLoc(), Init->getEndLoc(), {Init}); + if (Expr *E = Recovery.get()) + VDecl->setInit(E); + return; + } + // WebAssembly tables can't be used to initialise a variable. if (Init && !Init->getType().isNull() && Init->getType()->isWebAssemblyTableType()) { @@ -15899,6 +15914,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, FD->setInvalidDecl(); return D; } + + // Some function attributes (like OptimizeNoneAttr) need actions before + // parsing body started. + applyFunctionAttributesBeforeParsingBody(D); + // We want to attach documentation to original Decl (which might be // a function template). ActOnDocumentableDecl(D); @@ -15910,6 +15930,20 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, return D; } +void Sema::applyFunctionAttributesBeforeParsingBody(Decl *FD) { + if (!FD || FD->isInvalidDecl()) + return; + if (auto *TD = dyn_cast(FD)) + FD = TD->getTemplatedDecl(); + if (FD && FD->hasAttr()) { + FPOptionsOverride FPO; + FPO.setDisallowOptimizations(); + CurFPFeatures.applyChanges(FPO); + FpPragmaStack.CurrentValue = + CurFPFeatures.getChangesFrom(FPOptions(LangOpts)); + } +} + /// Given the set of return statements within a function body, /// compute the variables that are subject to the named return value /// optimization. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index abdbc9d8830c..338b0ec1e099 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -910,6 +910,8 @@ Sema::ActOnDecompositionDeclarator(Scope *S, Declarator &D, auto *BD = BindingDecl::Create(Context, DC, B.NameLoc, VarName); + ProcessDeclAttributeList(S, BD, *B.Attrs); + // Find the shadowed declaration before filtering for scope. NamedDecl *ShadowedDecl = D.getCXXScopeSpec().isEmpty() ? getShadowedDeclaration(BD, Previous) @@ -12052,11 +12054,17 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { Template = Specialization->getSpecializedTemplate(); Arguments = Specialization->getTemplateArgs().data(); - } else if (const TemplateSpecializationType *TST = - Ty->getAs()) { - Template = dyn_cast_or_null( - TST->getTemplateName().getAsTemplateDecl()); - Arguments = TST->template_arguments().begin(); + } else { + const TemplateSpecializationType *TST = nullptr; + if (auto *ICN = Ty->getAs()) + TST = ICN->getInjectedTST(); + else + TST = Ty->getAs(); + if (TST) { + Template = dyn_cast_or_null( + TST->getTemplateName().getAsTemplateDecl()); + Arguments = TST->template_arguments().begin(); + } } if (!Template) return false; diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 74d6f0700b0e..934ba174a426 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -494,6 +494,10 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) { } } } + + // Some function attributes (like OptimizeNoneAttr) need actions before + // parsing body started. + applyFunctionAttributesBeforeParsingBody(D); } namespace { diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index 00384f9dc16a..c9dd6bb2413e 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1314,7 +1314,7 @@ CanThrowResult Sema::canThrow(const Stmt *S) { // Some might be dependent for other reasons. case Expr::ArraySubscriptExprClass: case Expr::MatrixSubscriptExprClass: - case Expr::OMPArraySectionExprClass: + case Expr::ArraySectionExprClass: case Expr::OMPArrayShapingExprClass: case Expr::OMPIteratorExprClass: case Expr::BinaryOperatorClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 5c861467bc10..50f92c496a53 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5069,11 +5069,18 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation rbLoc) { if (base && !base->getType().isNull() && - base->hasPlaceholderType(BuiltinType::OMPArraySection)) - return OpenMP().ActOnOMPArraySectionExpr(base, lbLoc, ArgExprs.front(), - SourceLocation(), SourceLocation(), - /*Length*/ nullptr, - /*Stride=*/nullptr, rbLoc); + base->hasPlaceholderType(BuiltinType::ArraySection)) { + auto *AS = cast(base); + if (AS->isOMPArraySection()) + return OpenMP().ActOnOMPArraySectionExpr( + base, lbLoc, ArgExprs.front(), SourceLocation(), SourceLocation(), + /*Length*/ nullptr, + /*Stride=*/nullptr, rbLoc); + + return OpenACC().ActOnArraySectionExpr(base, lbLoc, ArgExprs.front(), + SourceLocation(), /*Length*/ nullptr, + rbLoc); + } // Since this might be a postfix expression, get rid of ParenListExprs. if (isa(base)) { @@ -6361,7 +6368,7 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { case BuiltinType::BoundMember: case BuiltinType::BuiltinFn: case BuiltinType::IncompleteMatrixIdx: - case BuiltinType::OMPArraySection: + case BuiltinType::ArraySection: case BuiltinType::OMPArrayShaping: case BuiltinType::OMPIterator: return true; @@ -21343,8 +21350,9 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { return ExprError(); // Expressions of unknown type. - case BuiltinType::OMPArraySection: - Diag(E->getBeginLoc(), diag::err_omp_array_section_use); + case BuiltinType::ArraySection: + Diag(E->getBeginLoc(), diag::err_array_section_use) + << cast(E)->isOMPArraySection(); return ExprError(); // Expressions of unknown type. diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 793e16df1789..7d9eaf672046 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -7753,9 +7753,9 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, break; } - case Stmt::OMPArraySectionExprClass: { + case Stmt::ArraySectionExprClass: { visitLocalsRetainedByInitializer(Path, - cast(Init)->getBase(), + cast(Init)->getBase(), Visit, true, EnableLifetimeWarnings); break; } @@ -8340,8 +8340,17 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity, << Entity.getType()->isReferenceType() << CLE->getInitializer() << 2 << DiagRange; } else { - Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref) - << Entity.getType()->isReferenceType() << DiagRange; + // P2748R5: Disallow Binding a Returned Glvalue to a Temporary. + // [stmt.return]/p6: In a function whose return type is a reference, + // other than an invented function for std::is_convertible ([meta.rel]), + // a return statement that binds the returned reference to a temporary + // expression ([class.temporary]) is ill-formed. + if (getLangOpts().CPlusPlus26 && Entity.getType()->isReferenceType()) + Diag(DiagLoc, diag::err_ret_local_temp_ref) + << Entity.getType()->isReferenceType() << DiagRange; + else + Diag(DiagLoc, diag::warn_ret_local_temp_addr_ref) + << Entity.getType()->isReferenceType() << DiagRange; } break; } @@ -10790,8 +10799,6 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( // FIXME: Perform "exact type" matching first, per CWG discussion? // Or implement this via an implied 'T(T) -> T' deduction guide? - // FIXME: Do we need/want a std::initializer_list special case? - // Look up deduction guides, including those synthesized from constructors. // // C++1z [over.match.class.deduct]p1: diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index ba69e71e30a1..d5cfe82a5d70 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -423,6 +423,21 @@ ExprResult SemaOpenACC::ActOnIntExpr(OpenACCDirectiveKind DK, return IntExpr; } +ExprResult SemaOpenACC::ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, + Expr *LowerBound, + SourceLocation ColonLoc, + Expr *Length, + SourceLocation RBLoc) { + ASTContext &Context = getASTContext(); + + // TODO OpenACC: We likely have to reproduce a lot of the same logic from the + // OMP version of this, but at the moment we don't have a good way to test it, + // so for now we'll just create the node. + return new (Context) + ArraySectionExpr(Base, LowerBound, Length, Context.ArraySectionTy, + VK_LValue, OK_Ordinary, ColonLoc, RBLoc); +} + bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc) { return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 5ba09926acf2..cee8da495c54 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -2230,7 +2230,7 @@ bool SemaOpenMP::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, dyn_cast(Last->getAssociatedExpression()); if ((UO && UO->getOpcode() == UO_Deref) || isa(Last->getAssociatedExpression()) || - isa(Last->getAssociatedExpression()) || + isa(Last->getAssociatedExpression()) || isa(EI->getAssociatedExpression()) || isa(Last->getAssociatedExpression())) { IsVariableAssociatedWithSection = true; @@ -3884,7 +3884,7 @@ public: MappableComponent &MC) { return MC.getAssociatedDeclaration() == nullptr && - (isa( + (isa( MC.getAssociatedExpression()) || isa( MC.getAssociatedExpression()) || @@ -4062,7 +4062,7 @@ public: // Do both expressions have the same kind? if (CCI->getAssociatedExpression()->getStmtClass() != SC.getAssociatedExpression()->getStmtClass()) - if (!((isa( + if (!((isa( SC.getAssociatedExpression()) || isa( SC.getAssociatedExpression())) && @@ -5428,9 +5428,9 @@ static std::pair getPrivateItem(Sema &S, Expr *&RefExpr, Base = TempASE->getBase()->IgnoreParenImpCasts(); RefExpr = Base; IsArrayExpr = ArraySubscript; - } else if (auto *OASE = dyn_cast_or_null(RefExpr)) { + } else if (auto *OASE = dyn_cast_or_null(RefExpr)) { Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); - while (auto *TempOASE = dyn_cast(Base)) + while (auto *TempOASE = dyn_cast(Base)) Base = TempOASE->getBase()->IgnoreParenImpCasts(); while (auto *TempASE = dyn_cast(Base)) Base = TempASE->getBase()->IgnoreParenImpCasts(); @@ -6060,10 +6060,10 @@ processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, // Array section - need to check for the mapping of the array section // element. QualType CanonType = E->getType().getCanonicalType(); - if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { - const auto *OASE = cast(E->IgnoreParenImpCasts()); + if (CanonType->isSpecificBuiltinType(BuiltinType::ArraySection)) { + const auto *OASE = cast(E->IgnoreParenImpCasts()); QualType BaseType = - OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + ArraySectionExpr::getBaseOriginalType(OASE->getBase()); QualType ElemType; if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) ElemType = ATy->getElementType(); @@ -19513,7 +19513,7 @@ struct ReductionData { } // namespace static bool checkOMPArraySectionConstantForReduction( - ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, + ASTContext &Context, const ArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl &ArraySizes) { const Expr *Length = OASE->getLength(); if (Length == nullptr) { @@ -19540,7 +19540,7 @@ static bool checkOMPArraySectionConstantForReduction( // We require length = 1 for all array sections except the right-most to // guarantee that the memory region is contiguous and has no holes in it. - while (const auto *TempOASE = dyn_cast(Base)) { + while (const auto *TempOASE = dyn_cast(Base)) { Length = TempOASE->getLength(); if (Length == nullptr) { // For array sections of the form [1:] or [:], we would need to analyze @@ -19745,12 +19745,12 @@ static bool actOnOMPReductionKindClause( Expr *TaskgroupDescriptor = nullptr; QualType Type; auto *ASE = dyn_cast(RefExpr->IgnoreParens()); - auto *OASE = dyn_cast(RefExpr->IgnoreParens()); + auto *OASE = dyn_cast(RefExpr->IgnoreParens()); if (ASE) { Type = ASE->getType().getNonReferenceType(); } else if (OASE) { QualType BaseType = - OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + ArraySectionExpr::getBaseOriginalType(OASE->getBase()); if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) Type = ATy->getElementType(); else @@ -21284,10 +21284,10 @@ OMPClause *SemaOpenMP::ActOnOpenMPDependClause( // List items used in depend clauses cannot be zero-length array // sections. QualType ExprTy = RefExpr->getType().getNonReferenceType(); - const auto *OASE = dyn_cast(SimpleExpr); + const auto *OASE = dyn_cast(SimpleExpr); if (OASE) { QualType BaseType = - OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + ArraySectionExpr::getBaseOriginalType(OASE->getBase()); if (BaseType.isNull()) return nullptr; if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) @@ -21346,7 +21346,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPDependClause( Res = SemaRef.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); } - if (!Res.isUsable() && !isa(SimpleExpr) && + if (!Res.isUsable() && !isa(SimpleExpr) && !isa(SimpleExpr)) { Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << (getLangOpts().OpenMP >= 50 ? 1 : 0) @@ -21447,7 +21447,7 @@ static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy) { - const auto *OASE = dyn_cast(E); + const auto *OASE = dyn_cast(E); // If this is an array subscript, it refers to the whole size if the size of // the dimension is constant and equals 1. Also, an array section assumes the @@ -21505,7 +21505,7 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy) { - const auto *OASE = dyn_cast(E); + const auto *OASE = dyn_cast(E); // An array subscript always refer to a single element. Also, an array section // assumes the format of an array subscript if no colon is used. @@ -21720,14 +21720,14 @@ public: return RelevantExpr || Visit(E); } - bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { + bool VisitArraySectionExpr(ArraySectionExpr *OASE) { // After OMP 5.0 Array section in reduction clause will be implicitly // mapped assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && "Array sections cannot be implicitly mapped."); Expr *E = OASE->getBase()->IgnoreParenImpCasts(); QualType CurType = - OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); + ArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] // If the type of a list item is a reference to a type T then the type @@ -21900,7 +21900,7 @@ static const Expr *checkMapClauseExpressionBase( auto CE = CurComponents.rend(); for (; CI != CE; ++CI) { const auto *OASE = - dyn_cast(CI->getAssociatedExpression()); + dyn_cast(CI->getAssociatedExpression()); if (!OASE) continue; if (OASE && OASE->getLength()) @@ -21970,10 +21970,10 @@ static bool checkMapConflicts( // variable in map clauses of the same construct. if (CurrentRegionOnly && (isa(CI->getAssociatedExpression()) || - isa(CI->getAssociatedExpression()) || + isa(CI->getAssociatedExpression()) || isa(CI->getAssociatedExpression())) && (isa(SI->getAssociatedExpression()) || - isa(SI->getAssociatedExpression()) || + isa(SI->getAssociatedExpression()) || isa(SI->getAssociatedExpression()))) { SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), diag::err_omp_multiple_array_items_in_map_clause) @@ -22001,11 +22001,10 @@ static bool checkMapConflicts( if (const auto *ASE = dyn_cast(SI->getAssociatedExpression())) { Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); - } else if (const auto *OASE = dyn_cast( + } else if (const auto *OASE = dyn_cast( SI->getAssociatedExpression())) { const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); - Type = - OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); + Type = ArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); } else if (const auto *OASE = dyn_cast( SI->getAssociatedExpression())) { Type = OASE->getBase()->getType()->getPointeeType(); @@ -22480,13 +22479,13 @@ static void checkMappableExpressionList( (void)I; QualType Type; auto *ASE = dyn_cast(VE->IgnoreParens()); - auto *OASE = dyn_cast(VE->IgnoreParens()); + auto *OASE = dyn_cast(VE->IgnoreParens()); auto *OAShE = dyn_cast(VE->IgnoreParens()); if (ASE) { Type = ASE->getType().getNonReferenceType(); } else if (OASE) { QualType BaseType = - OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); + ArraySectionExpr::getBaseOriginalType(OASE->getBase()); if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) Type = ATy->getElementType(); else @@ -23955,7 +23954,7 @@ SemaOpenMP::ActOnOpenMPUseDeviceAddrClause(ArrayRef VarList, MVLI.VarBaseDeclarations.push_back(D); MVLI.VarComponents.emplace_back(); Expr *Component = SimpleRefExpr; - if (VD && (isa(RefExpr->IgnoreParenImpCasts()) || + if (VD && (isa(RefExpr->IgnoreParenImpCasts()) || isa(RefExpr->IgnoreParenImpCasts()))) Component = SemaRef.DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); @@ -24105,7 +24104,7 @@ SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef VarList, // against other clauses later on. Expr *Component = SimpleRefExpr; auto *VD = dyn_cast(D); - if (VD && (isa(RefExpr->IgnoreParenImpCasts()) || + if (VD && (isa(RefExpr->IgnoreParenImpCasts()) || isa(RefExpr->IgnoreParenImpCasts()))) Component = SemaRef.DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); @@ -24519,7 +24518,7 @@ OMPClause *SemaOpenMP::ActOnOpenMPAffinityClause( Sema::TentativeAnalysisScope Trap(SemaRef); Res = SemaRef.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); } - if (!Res.isUsable() && !isa(SimpleExpr) && + if (!Res.isUsable() && !isa(SimpleExpr) && !isa(SimpleExpr)) { Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) << 1 << 0 << RefExpr->getSourceRange(); @@ -24632,7 +24631,7 @@ ExprResult SemaOpenMP::ActOnOMPArraySectionExpr( Expr *Stride, SourceLocation RBLoc) { ASTContext &Context = getASTContext(); if (Base->hasPlaceholderType() && - !Base->hasPlaceholderType(BuiltinType::OMPArraySection)) { + !Base->hasPlaceholderType(BuiltinType::ArraySection)) { ExprResult Result = SemaRef.CheckPlaceholderExpr(Base); if (Result.isInvalid()) return ExprError(); @@ -24672,13 +24671,13 @@ ExprResult SemaOpenMP::ActOnOMPArraySectionExpr( (LowerBound->isTypeDependent() || LowerBound->isValueDependent())) || (Length && (Length->isTypeDependent() || Length->isValueDependent())) || (Stride && (Stride->isTypeDependent() || Stride->isValueDependent()))) { - return new (Context) OMPArraySectionExpr( + return new (Context) ArraySectionExpr( Base, LowerBound, Length, Stride, Context.DependentTy, VK_LValue, OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc); } // Perform default conversions. - QualType OriginalTy = OMPArraySectionExpr::getBaseOriginalType(Base); + QualType OriginalTy = ArraySectionExpr::getBaseOriginalType(Base); QualType ResultTy; if (OriginalTy->isAnyPointerType()) { ResultTy = OriginalTy->getPointeeType(); @@ -24801,14 +24800,14 @@ ExprResult SemaOpenMP::ActOnOMPArraySectionExpr( } } - if (!Base->hasPlaceholderType(BuiltinType::OMPArraySection)) { + if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) { ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base); if (Result.isInvalid()) return ExprError(); Base = Result.get(); } - return new (Context) OMPArraySectionExpr( - Base, LowerBound, Length, Stride, Context.OMPArraySectionTy, VK_LValue, + return new (Context) ArraySectionExpr( + Base, LowerBound, Length, Stride, Context.ArraySectionTy, VK_LValue, OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc); } diff --git a/clang/lib/Sema/SemaRISCVVectorLookup.cpp b/clang/lib/Sema/SemaRISCVVectorLookup.cpp index bf89a4ac51af..26e13e87b1d6 100644 --- a/clang/lib/Sema/SemaRISCVVectorLookup.cpp +++ b/clang/lib/Sema/SemaRISCVVectorLookup.cpp @@ -216,6 +216,7 @@ void RISCVIntrinsicManagerImpl::ConstructRVVIntrinsics( {"zvksed", RVV_REQ_Zvksed}, {"zvksh", RVV_REQ_Zvksh}, {"zvfbfwma", RVV_REQ_Zvfbfwma}, + {"zvfbfmin", RVV_REQ_Zvfbfmin}, {"experimental", RVV_REQ_Experimental}}; // Construction of RVVIntrinsicRecords need to sync with createRVVIntrinsics diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp index 9d44c22c8ddc..1c84830b6ddd 100644 --- a/clang/lib/Sema/SemaStmtAttr.cpp +++ b/clang/lib/Sema/SemaStmtAttr.cpp @@ -109,16 +109,14 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const ParsedAttr &A, SetHints(LoopHintAttr::Unroll, LoopHintAttr::Disable); } else if (PragmaName == "unroll") { // #pragma unroll N - if (ValueExpr && !ValueExpr->isValueDependent()) { - llvm::APSInt ValueAPS; - ExprResult R = S.VerifyIntegerConstantExpression(ValueExpr, &ValueAPS); - assert(!R.isInvalid() && "unroll count value must be a valid value, it's " - "should be checked in Sema::CheckLoopHintExpr"); - (void)R; - // The values of 0 and 1 block any unrolling of the loop. - if (ValueAPS.isZero() || ValueAPS.isOne()) - SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Disable); - else + if (ValueExpr) { + if (!ValueExpr->isValueDependent()) { + auto Value = ValueExpr->EvaluateKnownConstInt(S.getASTContext()); + if (Value.isZero() || Value.isOne()) + SetHints(LoopHintAttr::Unroll, LoopHintAttr::Disable); + else + SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric); + } else SetHints(LoopHintAttr::UnrollCount, LoopHintAttr::Numeric); } else SetHints(LoopHintAttr::Unroll, LoopHintAttr::Enable); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4bda31ba67c0..bbcb7c33a985 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -9460,6 +9460,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) << ClassTemplate->getDeclName(); isPartialSpecialization = false; + Invalid = true; } } @@ -9675,6 +9676,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization( if (SkipBody && SkipBody->ShouldSkip) return SkipBody->Previous; + Specialization->setInvalidDecl(Invalid); return Specialization; } diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 0b6375001f53..c3815bca0385 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -1914,6 +1914,9 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( if (!S.isCompleteType(Info.getLocation(), A)) return Result; + if (getCanonicalRD(A)->isInvalidDecl()) + return Result; + // Reset the incorrectly deduced argument from above. Deduced = DeducedOrig; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 98d5c7cb3a8a..3a9fd906b7af 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2151,13 +2151,25 @@ TemplateInstantiator::TransformLoopHintAttr(const LoopHintAttr *LH) { // Generate error if there is a problem with the value. if (getSema().CheckLoopHintExpr(TransformedExpr, LH->getLocation(), - LH->getOption() == LoopHintAttr::UnrollCount)) + LH->getSemanticSpelling() == + LoopHintAttr::Pragma_unroll)) return LH; + LoopHintAttr::OptionType Option = LH->getOption(); + LoopHintAttr::LoopHintState State = LH->getState(); + + llvm::APSInt ValueAPS = + TransformedExpr->EvaluateKnownConstInt(getSema().getASTContext()); + // The values of 0 and 1 block any unrolling of the loop. + if (ValueAPS.isZero() || ValueAPS.isOne()) { + Option = LoopHintAttr::Unroll; + State = LoopHintAttr::Disable; + } + // Create new LoopHintValueAttr with integral expression in place of the // non-type template parameter. - return LoopHintAttr::CreateImplicit(getSema().Context, LH->getOption(), - LH->getState(), TransformedExpr, *LH); + return LoopHintAttr::CreateImplicit(getSema().Context, Option, State, + TransformedExpr, *LH); } const NoInlineAttr *TemplateInstantiator::TransformStmtNoInlineAttr( const Stmt *OrigS, const Stmt *InstS, const NoInlineAttr *A) { diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 787a485e0b2f..d544cfac55ba 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5184,6 +5184,7 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, ParmVarDecl *Parm = Function->getParamDecl(0); TypeSourceInfo *NewParmSI = IR.TransformType(Parm->getTypeSourceInfo()); + assert(NewParmSI && "Type transformation failed."); Parm->setType(NewParmSI->getType()); Parm->setTypeSourceInfo(NewParmSI); }; diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 9404be5a46f3..f47bc219e6fa 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2784,15 +2784,23 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc, - Expr *LowerBound, - SourceLocation ColonLocFirst, - SourceLocation ColonLocSecond, - Expr *Length, Expr *Stride, - SourceLocation RBracketLoc) { - return getSema().OpenMP().ActOnOMPArraySectionExpr( - Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length, - Stride, RBracketLoc); + ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base, + SourceLocation LBracketLoc, + Expr *LowerBound, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, + Expr *Length, Expr *Stride, + SourceLocation RBracketLoc) { + if (IsOMPArraySection) + return getSema().OpenMP().ActOnOMPArraySectionExpr( + Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length, + Stride, RBracketLoc); + + assert(Stride == nullptr && !ColonLocSecond.isValid() && + "Stride/second colon not allowed for OpenACC"); + + return getSema().OpenACC().ActOnArraySectionExpr( + Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc); } /// Build a new array shaping expression. @@ -11742,7 +11750,7 @@ TreeTransform::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) { template ExprResult -TreeTransform::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { +TreeTransform::TransformArraySectionExpr(ArraySectionExpr *E) { ExprResult Base = getDerived().TransformExpr(E->getBase()); if (Base.isInvalid()) return ExprError(); @@ -11762,20 +11770,25 @@ TreeTransform::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { } ExprResult Stride; - if (Expr *Str = E->getStride()) { - Stride = getDerived().TransformExpr(Str); - if (Stride.isInvalid()) - return ExprError(); + if (E->isOMPArraySection()) { + if (Expr *Str = E->getStride()) { + Stride = getDerived().TransformExpr(Str); + if (Stride.isInvalid()) + return ExprError(); + } } if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && - LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength()) + LowerBound.get() == E->getLowerBound() && + Length.get() == E->getLength() && + (E->isOpenACCArraySection() || Stride.get() == E->getStride())) return E; - return getDerived().RebuildOMPArraySectionExpr( - Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), - E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(), - E->getRBracketLoc()); + return getDerived().RebuildArraySectionExpr( + E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(), + LowerBound.get(), E->getColonLocFirst(), + E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{}, + Length.get(), Stride.get(), E->getRBracketLoc()); } template @@ -14186,6 +14199,8 @@ TreeTransform::TransformLambdaExpr(LambdaExpr *E) { // FIXME: Sema's lambda-building mechanism expects us to push an expression // evaluation context even if we're not transforming the function body. getSema().PushExpressionEvaluationContext( + E->getCallOperator()->isConsteval() ? + Sema::ExpressionEvaluationContext::ImmediateFunctionContext : Sema::ExpressionEvaluationContext::PotentiallyEvaluated); Sema::CodeSynthesisContext C; diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index f8d54c0c3989..e017f5bdb488 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -261,8 +261,8 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::IncompleteMatrixIdx: ID = PREDEF_TYPE_INCOMPLETE_MATRIX_IDX; break; - case BuiltinType::OMPArraySection: - ID = PREDEF_TYPE_OMP_ARRAY_SECTION; + case BuiltinType::ArraySection: + ID = PREDEF_TYPE_ARRAY_SECTION; break; case BuiltinType::OMPArrayShaping: ID = PREDEF_TYPE_OMP_ARRAY_SHAPING; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index d64925676df7..0ef57a3ea804 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -954,14 +954,16 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d, // Load instance methods for (unsigned I = 0; I != NumInstanceMethods; ++I) { if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs( - F, endian::readNext(d))) + F, + LocalDeclID(endian::readNext(d)))) Result.Instance.push_back(Method); } // Load factory methods for (unsigned I = 0; I != NumFactoryMethods; ++I) { if (ObjCMethodDecl *Method = Reader.GetLocalDeclAs( - F, endian::readNext(d))) + F, + LocalDeclID(endian::readNext(d)))) Result.Factory.push_back(Method); } @@ -1088,10 +1090,11 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, // Read all of the declarations visible at global scope with this // name. if (DataLen > 0) { - SmallVector DeclIDs; - for (; DataLen > 0; DataLen -= 4) + SmallVector DeclIDs; + for (; DataLen > 0; DataLen -= sizeof(DeclID)) DeclIDs.push_back(Reader.getGlobalDeclID( - F, endian::readNext(d))); + F, + LocalDeclID(endian::readNext(d)))); Reader.SetGloballyVisibleDecls(II, DeclIDs); } @@ -1211,8 +1214,8 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type, data_type_builder &Val) { using namespace llvm::support; - for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) { - uint32_t LocalID = endian::readNext(d); + for (unsigned NumDecls = DataLen / sizeof(DeclID); NumDecls; --NumDecls) { + LocalDeclID LocalID(endian::readNext(d)); Val.insert(Reader.getGlobalDeclID(F, LocalID)); } } @@ -1259,9 +1262,8 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, if (!Lex.first) { Lex = std::make_pair( &M, llvm::ArrayRef( - reinterpret_cast( - Blob.data()), - Blob.size() / 4)); + reinterpret_cast(Blob.data()), + Blob.size() / sizeof(DeclID))); } DC->setHasExternalLexicalStorage(true); return false; @@ -1270,7 +1272,7 @@ bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M, BitstreamCursor &Cursor, uint64_t Offset, - DeclID ID) { + GlobalDeclID ID) { assert(Offset != 0); SavedStreamPosition SavedPosition(Cursor); @@ -1653,7 +1655,7 @@ bool ASTReader::ReadSLocEntry(int ID) { unsigned NumFileDecls = Record[7]; if (NumFileDecls && ContextObj) { - const DeclID *FirstDecl = F->FileSortedDecls + Record[6]; + const LocalDeclID *FirstDecl = F->FileSortedDecls + Record[6]; assert(F->FileSortedDecls && "FILE_SORTED_DECLS not encountered yet ?"); FileDeclIDs[FID] = FileDeclsInfo(F, llvm::ArrayRef(FirstDecl, NumFileDecls)); @@ -3369,8 +3371,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, if (F.LocalNumDecls > 0) { // Introduce the global -> local mapping for declarations within this // module. - GlobalDeclMap.insert( - std::make_pair(getTotalNumDecls() + NUM_PREDEF_DECL_IDS, &F)); + GlobalDeclMap.insert(std::make_pair( + GlobalDeclID(getTotalNumDecls() + NUM_PREDEF_DECL_IDS), &F)); // Introduce the local -> global mapping for declarations within this // module. @@ -3389,9 +3391,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case TU_UPDATE_LEXICAL: { DeclContext *TU = ContextObj->getTranslationUnitDecl(); LexicalContents Contents( - reinterpret_cast( - Blob.data()), - static_cast(Blob.size() / 4)); + reinterpret_cast(Blob.data()), + static_cast(Blob.size() / sizeof(DeclID))); TULexicalDecls.push_back(std::make_pair(&F, Contents)); TU->setHasExternalLexicalStorage(true); break; @@ -3399,7 +3400,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case UPDATE_VISIBLE: { unsigned Idx = 0; - serialization::DeclID ID = ReadDeclID(F, Record, Idx); + GlobalDeclID ID = ReadDeclID(F, Record, Idx); auto *Data = (const unsigned char*)Blob.data(); PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data}); // If we've already loaded the decl, perform the updates when we finish @@ -3460,7 +3461,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, // FIXME: Skip reading this record if our ASTConsumer doesn't care // about "interesting" decls (for instance, if we're building a module). for (unsigned I = 0, N = Record.size(); I != N; ++I) - EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); + EagerlyDeserializedDecls.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case MODULAR_CODEGEN_DECLS: @@ -3469,7 +3471,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, if (F.Kind == MK_MainFile || getContext().getLangOpts().BuildingPCHWithObjectFile) for (unsigned I = 0, N = Record.size(); I != N; ++I) - EagerlyDeserializedDecls.push_back(getGlobalDeclID(F, Record[I])); + EagerlyDeserializedDecls.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case SPECIAL_TYPES: @@ -3501,12 +3504,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case UNUSED_FILESCOPED_DECLS: for (unsigned I = 0, N = Record.size(); I != N; ++I) - UnusedFileScopedDecls.push_back(getGlobalDeclID(F, Record[I])); + UnusedFileScopedDecls.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case DELEGATING_CTORS: for (unsigned I = 0, N = Record.size(); I != N; ++I) - DelegatingCtorDecls.push_back(getGlobalDeclID(F, Record[I])); + DelegatingCtorDecls.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case WEAK_UNDECLARED_IDENTIFIERS: @@ -3614,7 +3619,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; case FILE_SORTED_DECLS: - F.FileSortedDecls = (const DeclID *)Blob.data(); + F.FileSortedDecls = (const LocalDeclID *)Blob.data(); F.NumFileSortedDecls = Record[0]; break; @@ -3669,7 +3674,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case EXT_VECTOR_DECLS: for (unsigned I = 0, N = Record.size(); I != N; ++I) - ExtVectorDecls.push_back(getGlobalDeclID(F, Record[I])); + ExtVectorDecls.push_back(getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case VTABLE_USES: @@ -3683,18 +3688,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, VTableUses.clear(); for (unsigned Idx = 0, N = Record.size(); Idx != N; /* In loop */) { - VTableUses.push_back(getGlobalDeclID(F, Record[Idx++])); VTableUses.push_back( - ReadSourceLocation(F, Record, Idx).getRawEncoding()); - VTableUses.push_back(Record[Idx++]); + {getGlobalDeclID(F, LocalDeclID(Record[Idx++])), + ReadSourceLocation(F, Record, Idx).getRawEncoding(), + (bool)Record[Idx++]}); } break; case PENDING_IMPLICIT_INSTANTIATIONS: - if (PendingInstantiations.size() % 2 != 0) - return llvm::createStringError( - std::errc::illegal_byte_sequence, - "Invalid existing PendingInstantiations"); if (Record.size() % 2 != 0) return llvm::createStringError( @@ -3702,9 +3703,9 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "Invalid PENDING_IMPLICIT_INSTANTIATIONS block"); for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) { - PendingInstantiations.push_back(getGlobalDeclID(F, Record[I++])); PendingInstantiations.push_back( - ReadSourceLocation(F, Record, I).getRawEncoding()); + {getGlobalDeclID(F, LocalDeclID(Record[I++])), + ReadSourceLocation(F, Record, I).getRawEncoding()}); } break; @@ -3713,7 +3714,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, return llvm::createStringError(std::errc::illegal_byte_sequence, "Invalid SEMA_DECL_REFS block"); for (unsigned I = 0, N = Record.size(); I != N; ++I) - SemaDeclRefs.push_back(getGlobalDeclID(F, Record[I])); + SemaDeclRefs.push_back(getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case PPD_ENTITIES_OFFSETS: { @@ -3772,7 +3773,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, std::errc::illegal_byte_sequence, "invalid DECL_UPDATE_OFFSETS block in AST file"); for (unsigned I = 0, N = Record.size(); I != N; I += 2) { - GlobalDeclID ID = getGlobalDeclID(F, Record[I]); + GlobalDeclID ID = getGlobalDeclID(F, LocalDeclID(Record[I])); DeclUpdateOffsets[ID].push_back(std::make_pair(&F, Record[I + 1])); // If we've already loaded the decl, perform the updates when we finish @@ -3790,7 +3791,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, "invalid DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD block in AST " "file"); for (unsigned I = 0, N = Record.size(); I != N; I += 3) { - GlobalDeclID ID = getGlobalDeclID(F, Record[I]); + GlobalDeclID ID = getGlobalDeclID(F, LocalDeclID(Record[I])); uint64_t BaseOffset = F.DeclsBlockStartOffset; assert(BaseOffset && "Invalid DeclsBlockStartOffset for module file!"); @@ -3825,7 +3826,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, // FIXME: Modules will have trouble with this. CUDASpecialDeclRefs.clear(); for (unsigned I = 0, N = Record.size(); I != N; ++I) - CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I])); + CUDASpecialDeclRefs.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case HEADER_SEARCH_TABLE: @@ -3866,32 +3868,30 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case TENTATIVE_DEFINITIONS: for (unsigned I = 0, N = Record.size(); I != N; ++I) - TentativeDefinitions.push_back(getGlobalDeclID(F, Record[I])); + TentativeDefinitions.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case KNOWN_NAMESPACES: for (unsigned I = 0, N = Record.size(); I != N; ++I) - KnownNamespaces.push_back(getGlobalDeclID(F, Record[I])); + KnownNamespaces.push_back(getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case UNDEFINED_BUT_USED: - if (UndefinedButUsed.size() % 2 != 0) - return llvm::createStringError(std::errc::illegal_byte_sequence, - "Invalid existing UndefinedButUsed"); - if (Record.size() % 2 != 0) return llvm::createStringError(std::errc::illegal_byte_sequence, "invalid undefined-but-used record"); for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) { - UndefinedButUsed.push_back(getGlobalDeclID(F, Record[I++])); UndefinedButUsed.push_back( - ReadSourceLocation(F, Record, I).getRawEncoding()); + {getGlobalDeclID(F, LocalDeclID(Record[I++])), + ReadSourceLocation(F, Record, I).getRawEncoding()}); } break; case DELETE_EXPRS_TO_ANALYZE: for (unsigned I = 0, N = Record.size(); I != N;) { - DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++])); + DelayedDeleteExprs.push_back( + getGlobalDeclID(F, LocalDeclID(Record[I++])).get()); const uint64_t Count = Record[I++]; DelayedDeleteExprs.push_back(Count); for (uint64_t C = 0; C < Count; ++C) { @@ -3976,7 +3976,7 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES: for (unsigned I = 0, N = Record.size(); I != N; ++I) UnusedLocalTypedefNameCandidates.push_back( - getGlobalDeclID(F, Record[I])); + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; case CUDA_PRAGMA_FORCE_HOST_DEVICE_DEPTH: @@ -4032,7 +4032,8 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, case DECLS_TO_CHECK_FOR_DEFERRED_DIAGS: for (unsigned I = 0, N = Record.size(); I != N; ++I) - DeclsToCheckForDeferredDiags.insert(getGlobalDeclID(F, Record[I])); + DeclsToCheckForDeferredDiags.insert( + getGlobalDeclID(F, LocalDeclID(Record[I]))); break; } } @@ -4655,9 +4656,8 @@ ASTReader::ASTReadResult ASTReader::ReadAST(StringRef FileName, ModuleKind Type, // that we load any additional categories. if (ContextObj) { for (unsigned I = 0, N = ObjCClassesLoaded.size(); I != N; ++I) { - loadObjCCategories(ObjCClassesLoaded[I]->getGlobalID(), - ObjCClassesLoaded[I], - PreviousGeneration); + loadObjCCategories(GlobalDeclID(ObjCClassesLoaded[I]->getGlobalID()), + ObjCClassesLoaded[I], PreviousGeneration); } } @@ -5101,8 +5101,9 @@ void ASTReader::InitializeContext() { // If there's a listener, notify them that we "read" the translation unit. if (DeserializationListener) - DeserializationListener->DeclRead(PREDEF_DECL_TRANSLATION_UNIT_ID, - Context.getTranslationUnitDecl()); + DeserializationListener->DeclRead( + GlobalDeclID(PREDEF_DECL_TRANSLATION_UNIT_ID), + Context.getTranslationUnitDecl()); // FIXME: Find a better way to deal with collisions between these // built-in types. Right now, we just ignore the problem. @@ -6010,9 +6011,9 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F, case SUBMODULE_INITIALIZERS: { if (!ContextObj) break; - SmallVector Inits; + SmallVector Inits; for (auto &ID : Record) - Inits.push_back(getGlobalDeclID(F, ID)); + Inits.push_back(getGlobalDeclID(F, LocalDeclID(ID))); ContextObj->addLazyModuleInitializers(CurrentModule, Inits); break; } @@ -7384,11 +7385,11 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_INCOMPLETE_MATRIX_IDX: T = Context.IncompleteMatrixIdxTy; break; - case PREDEF_TYPE_OMP_ARRAY_SECTION: - T = Context.OMPArraySectionTy; + case PREDEF_TYPE_ARRAY_SECTION: + T = Context.ArraySectionTy; break; case PREDEF_TYPE_OMP_ARRAY_SHAPING: - T = Context.OMPArraySectionTy; + T = Context.OMPArrayShapingTy; break; case PREDEF_TYPE_OMP_ITERATOR: T = Context.OMPIteratorTy; @@ -7517,9 +7518,7 @@ ASTRecordReader::readASTTemplateArgumentListInfo() { return ASTTemplateArgumentListInfo::Create(getContext(), Result); } -Decl *ASTReader::GetExternalDecl(uint32_t ID) { - return GetDecl(ID); -} +Decl *ASTReader::GetExternalDecl(GlobalDeclID ID) { return GetDecl(ID); } void ASTReader::CompleteRedeclChain(const Decl *D) { if (NumCurrentElementsDeserializing) { @@ -7652,44 +7651,45 @@ CXXBaseSpecifier *ASTReader::GetExternalCXXBaseSpecifiers(uint64_t Offset) { return Bases; } -serialization::DeclID -ASTReader::getGlobalDeclID(ModuleFile &F, LocalDeclID LocalID) const { - if (LocalID < NUM_PREDEF_DECL_IDS) - return LocalID; +GlobalDeclID ASTReader::getGlobalDeclID(ModuleFile &F, + LocalDeclID LocalID) const { + DeclID ID = LocalID.get(); + if (ID < NUM_PREDEF_DECL_IDS) + return GlobalDeclID(ID); if (!F.ModuleOffsetMap.empty()) ReadModuleOffsetMap(F); - ContinuousRangeMap::iterator I - = F.DeclRemap.find(LocalID - NUM_PREDEF_DECL_IDS); + ContinuousRangeMap::iterator I = + F.DeclRemap.find(ID - NUM_PREDEF_DECL_IDS); assert(I != F.DeclRemap.end() && "Invalid index into decl index remap"); - return LocalID + I->second; + return GlobalDeclID(ID + I->second); } -bool ASTReader::isDeclIDFromModule(serialization::GlobalDeclID ID, - ModuleFile &M) const { +bool ASTReader::isDeclIDFromModule(GlobalDeclID ID, ModuleFile &M) const { // Predefined decls aren't from any module. - if (ID < NUM_PREDEF_DECL_IDS) + if (ID.get() < NUM_PREDEF_DECL_IDS) return false; - return ID - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && - ID - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; + return ID.get() - NUM_PREDEF_DECL_IDS >= M.BaseDeclID && + ID.get() - NUM_PREDEF_DECL_IDS < M.BaseDeclID + M.LocalNumDecls; } ModuleFile *ASTReader::getOwningModuleFile(const Decl *D) { if (!D->isFromASTFile()) return nullptr; - GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(D->getGlobalID()); + GlobalDeclMapType::const_iterator I = + GlobalDeclMap.find(GlobalDeclID(D->getGlobalID())); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); return I->second; } SourceLocation ASTReader::getSourceLocationForDeclID(GlobalDeclID ID) { - if (ID < NUM_PREDEF_DECL_IDS) + if (ID.get() < NUM_PREDEF_DECL_IDS) return SourceLocation(); - unsigned Index = ID - NUM_PREDEF_DECL_IDS; + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; if (Index > DeclsLoaded.size()) { Error("declaration ID out-of-range for AST file"); @@ -7763,9 +7763,9 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) { llvm_unreachable("PredefinedDeclIDs unknown enum value"); } -Decl *ASTReader::GetExistingDecl(DeclID ID) { +Decl *ASTReader::GetExistingDecl(GlobalDeclID ID) { assert(ContextObj && "reading decl with no AST context"); - if (ID < NUM_PREDEF_DECL_IDS) { + if (ID.get() < NUM_PREDEF_DECL_IDS) { Decl *D = getPredefinedDecl(*ContextObj, (PredefinedDeclIDs)ID); if (D) { // Track that we have merged the declaration with ID \p ID into the @@ -7777,7 +7777,7 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) { return D; } - unsigned Index = ID - NUM_PREDEF_DECL_IDS; + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7788,11 +7788,11 @@ Decl *ASTReader::GetExistingDecl(DeclID ID) { return DeclsLoaded[Index]; } -Decl *ASTReader::GetDecl(DeclID ID) { - if (ID < NUM_PREDEF_DECL_IDS) +Decl *ASTReader::GetDecl(GlobalDeclID ID) { + if (ID.get() < NUM_PREDEF_DECL_IDS) return GetExistingDecl(ID); - unsigned Index = ID - NUM_PREDEF_DECL_IDS; + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; if (Index >= DeclsLoaded.size()) { assert(0 && "declaration ID out-of-range for AST file"); @@ -7809,32 +7809,32 @@ Decl *ASTReader::GetDecl(DeclID ID) { return DeclsLoaded[Index]; } -DeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, - DeclID GlobalID) { - if (GlobalID < NUM_PREDEF_DECL_IDS) - return GlobalID; +LocalDeclID ASTReader::mapGlobalIDToModuleFileGlobalID(ModuleFile &M, + GlobalDeclID GlobalID) { + DeclID ID = GlobalID.get(); + if (ID < NUM_PREDEF_DECL_IDS) + return LocalDeclID(ID); GlobalDeclMapType::const_iterator I = GlobalDeclMap.find(GlobalID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); ModuleFile *Owner = I->second; - llvm::DenseMap::iterator Pos - = M.GlobalToLocalDeclIDs.find(Owner); + llvm::DenseMap::iterator Pos = + M.GlobalToLocalDeclIDs.find(Owner); if (Pos == M.GlobalToLocalDeclIDs.end()) - return 0; + return LocalDeclID(); - return GlobalID - Owner->BaseDeclID + Pos->second; + return LocalDeclID(ID - Owner->BaseDeclID + Pos->second); } -serialization::DeclID ASTReader::ReadDeclID(ModuleFile &F, - const RecordData &Record, - unsigned &Idx) { +GlobalDeclID ASTReader::ReadDeclID(ModuleFile &F, const RecordData &Record, + unsigned &Idx) { if (Idx >= Record.size()) { Error("Corrupted AST file"); - return 0; + return GlobalDeclID(0); } - return getGlobalDeclID(F, Record[Idx++]); + return getGlobalDeclID(F, LocalDeclID(Record[Idx++])); } /// Resolve the offset of a statement into a statement. @@ -7870,7 +7870,7 @@ void ASTReader::FindExternalLexicalDecls( if (!IsKindWeWant(K)) continue; - auto ID = (serialization::DeclID)+LexicalDecls[I + 1]; + auto ID = (DeclID) + LexicalDecls[I + 1]; // Don't add predefined declarations to the lexical context more // than once. @@ -7881,7 +7881,7 @@ void ASTReader::FindExternalLexicalDecls( PredefsVisited[ID] = true; } - if (Decl *D = GetLocalDecl(*M, ID)) { + if (Decl *D = GetLocalDecl(*M, LocalDeclID(ID))) { assert(D->getKind() == K && "wrong kind for lexical decl"); if (!DC->isDeclInLexicalTraversal(D)) Decls.push_back(D); @@ -7952,7 +7952,7 @@ void ASTReader::FindFileRegionDecls(FileID File, SourceLocation EndLoc = BeginLoc.getLocWithOffset(Length); DeclIDComp DIDComp(*this, *DInfo.Mod); - ArrayRef::iterator BeginIt = + ArrayRef::iterator BeginIt = llvm::lower_bound(DInfo.Decls, BeginLoc, DIDComp); if (BeginIt != DInfo.Decls.begin()) --BeginIt; @@ -7965,13 +7965,12 @@ void ASTReader::FindFileRegionDecls(FileID File, ->isTopLevelDeclInObjCContainer()) --BeginIt; - ArrayRef::iterator EndIt = + ArrayRef::iterator EndIt = llvm::upper_bound(DInfo.Decls, EndLoc, DIDComp); if (EndIt != DInfo.Decls.end()) ++EndIt; - for (ArrayRef::iterator - DIt = BeginIt; DIt != EndIt; ++DIt) + for (ArrayRef::iterator DIt = BeginIt; DIt != EndIt; ++DIt) Decls.push_back(GetDecl(getGlobalDeclID(*DInfo.Mod, *DIt))); } @@ -7992,7 +7991,8 @@ ASTReader::FindExternalVisibleDeclsByName(const DeclContext *DC, // Load the list of declarations. SmallVector Decls; llvm::SmallPtrSet Found; - for (DeclID ID : It->second.Table.find(Name)) { + + for (GlobalDeclID ID : It->second.Table.find(Name)) { NamedDecl *ND = cast(GetDecl(ID)); if (ND->getDeclName() == Name && Found.insert(ND).second) Decls.push_back(ND); @@ -8013,7 +8013,7 @@ void ASTReader::completeVisibleDeclsMap(const DeclContext *DC) { DeclsMap Decls; - for (DeclID ID : It->second.Table.findAll()) { + for (GlobalDeclID ID : It->second.Table.findAll()) { NamedDecl *ND = cast(GetDecl(ID)); Decls[ND->getDeclName()].push_back(ND); } @@ -8164,8 +8164,12 @@ dumpModuleIDMap(StringRef Name, llvm::errs() << Name << ":\n"; for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); I != IEnd; ++I) { - llvm::errs() << " " << I->first << " -> " << I->second->FileName - << "\n"; + uint64_t ID = 0; + if constexpr (std::is_integral_v) + ID = I->first; + else /*GlobalDeclID*/ + ID = I->first.get(); + llvm::errs() << " " << ID << " -> " << I->second->FileName << "\n"; } } @@ -8211,7 +8215,7 @@ void ASTReader::InitializeSema(Sema &S) { // Makes sure any declarations that were deserialized "too early" // still get added to the identifier's declaration chains. - for (uint64_t ID : PreloadedDeclIDs) { + for (GlobalDeclID ID : PreloadedDeclIDs) { NamedDecl *D = cast(GetDecl(ID)); pushExternalDeclIntoScope(D, D->getDeclName()); } @@ -8240,11 +8244,11 @@ void ASTReader::UpdateSema() { assert(SemaDeclRefs.size() % 3 == 0); for (unsigned I = 0; I != SemaDeclRefs.size(); I += 3) { if (!SemaObj->StdNamespace) - SemaObj->StdNamespace = SemaDeclRefs[I]; + SemaObj->StdNamespace = SemaDeclRefs[I].get(); if (!SemaObj->StdBadAlloc) - SemaObj->StdBadAlloc = SemaDeclRefs[I+1]; + SemaObj->StdBadAlloc = SemaDeclRefs[I + 1].get(); if (!SemaObj->StdAlignValT) - SemaObj->StdAlignValT = SemaDeclRefs[I+2]; + SemaObj->StdAlignValT = SemaDeclRefs[I + 2].get(); } SemaDeclRefs.clear(); } @@ -8617,18 +8621,20 @@ void ASTReader::ReadKnownNamespaces( void ASTReader::ReadUndefinedButUsed( llvm::MapVector &Undefined) { for (unsigned Idx = 0, N = UndefinedButUsed.size(); Idx != N;) { - NamedDecl *D = cast(GetDecl(UndefinedButUsed[Idx++])); - SourceLocation Loc = - SourceLocation::getFromRawEncoding(UndefinedButUsed[Idx++]); + UndefinedButUsedDecl &U = UndefinedButUsed[Idx++]; + NamedDecl *D = cast(GetDecl(U.ID)); + SourceLocation Loc = SourceLocation::getFromRawEncoding(U.RawLoc); Undefined.insert(std::make_pair(D, Loc)); } + UndefinedButUsed.clear(); } void ASTReader::ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector, 4>> & Exprs) { for (unsigned Idx = 0, N = DelayedDeleteExprs.size(); Idx != N;) { - FieldDecl *FD = cast(GetDecl(DelayedDeleteExprs[Idx++])); + FieldDecl *FD = + cast(GetDecl(GlobalDeclID(DelayedDeleteExprs[Idx++]))); uint64_t Count = DelayedDeleteExprs[Idx++]; for (uint64_t C = 0; C < Count; ++C) { SourceLocation DeleteLoc = @@ -8742,9 +8748,10 @@ void ASTReader::ReadWeakUndeclaredIdentifiers( void ASTReader::ReadUsedVTables(SmallVectorImpl &VTables) { for (unsigned Idx = 0, N = VTableUses.size(); Idx < N; /* In loop */) { ExternalVTableUse VT; - VT.Record = dyn_cast_or_null(GetDecl(VTableUses[Idx++])); - VT.Location = SourceLocation::getFromRawEncoding(VTableUses[Idx++]); - VT.DefinitionRequired = VTableUses[Idx++]; + VTableUse &TableInfo = VTableUses[Idx++]; + VT.Record = dyn_cast_or_null(GetDecl(TableInfo.ID)); + VT.Location = SourceLocation::getFromRawEncoding(TableInfo.RawLoc); + VT.DefinitionRequired = TableInfo.Used; VTables.push_back(VT); } @@ -8754,9 +8761,9 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl &VTables) { void ASTReader::ReadPendingInstantiations( SmallVectorImpl> &Pending) { for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { - ValueDecl *D = cast(GetDecl(PendingInstantiations[Idx++])); - SourceLocation Loc - = SourceLocation::getFromRawEncoding(PendingInstantiations[Idx++]); + PendingInstantiation &Inst = PendingInstantiations[Idx++]; + ValueDecl *D = cast(GetDecl(Inst.ID)); + SourceLocation Loc = SourceLocation::getFromRawEncoding(Inst.RawLoc); Pending.push_back(std::make_pair(D, Loc)); } @@ -8771,11 +8778,11 @@ void ASTReader::ReadLateParsedTemplates( RecordDataImpl &LateParsed = LPT.second; for (unsigned Idx = 0, N = LateParsed.size(); Idx < N; /* In loop */) { - FunctionDecl *FD = - cast(GetLocalDecl(*FMod, LateParsed[Idx++])); + FunctionDecl *FD = cast( + GetLocalDecl(*FMod, LocalDeclID(LateParsed[Idx++]))); auto LT = std::make_unique(); - LT->D = GetLocalDecl(*FMod, LateParsed[Idx++]); + LT->D = GetLocalDecl(*FMod, LocalDeclID(LateParsed[Idx++])); LT->FPO = FPOptions::getFromOpaqueInt(LateParsed[Idx++]); ModuleFile *F = getOwningModuleFile(LT->D); @@ -8833,10 +8840,9 @@ void ASTReader::SetIdentifierInfo(IdentifierID ID, IdentifierInfo *II) { /// \param Decls if non-null, this vector will be populated with the set of /// deserialized declarations. These declarations will not be pushed into /// scope. -void -ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II, - const SmallVectorImpl &DeclIDs, - SmallVectorImpl *Decls) { +void ASTReader::SetGloballyVisibleDecls( + IdentifierInfo *II, const SmallVectorImpl &DeclIDs, + SmallVectorImpl *Decls) { if (NumCurrentElementsDeserializing && !Decls) { PendingIdentifierInfos[II].append(DeclIDs.begin(), DeclIDs.end()); return; @@ -9184,9 +9190,9 @@ void ASTRecordReader::readUnresolvedSet(LazyASTUnresolvedSet &Set) { unsigned NumDecls = readInt(); Set.reserve(getContext(), NumDecls); while (NumDecls--) { - DeclID ID = readDeclID(); + GlobalDeclID ID = readDeclID(); AccessSpecifier AS = (AccessSpecifier) readInt(); - Set.addLazyDecl(getContext(), ID, AS); + Set.addLazyDecl(getContext(), ID.get(), AS); } } @@ -9560,7 +9566,7 @@ void ASTReader::finishPendingActions() { while (!PendingIdentifierInfos.empty()) { IdentifierInfo *II = PendingIdentifierInfos.back().first; - SmallVector DeclIDs = + SmallVector DeclIDs = std::move(PendingIdentifierInfos.back().second); PendingIdentifierInfos.pop_back(); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 74d40f7da34c..744f11de88c2 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -84,14 +84,14 @@ namespace clang { ASTReader &Reader; ASTRecordReader &Record; ASTReader::RecordLocation Loc; - const DeclID ThisDeclID; + const GlobalDeclID ThisDeclID; const SourceLocation ThisDeclLoc; using RecordData = ASTReader::RecordData; TypeID DeferredTypeID = 0; unsigned AnonymousDeclNumber = 0; - GlobalDeclID NamedDeclForTagDecl = 0; + GlobalDeclID NamedDeclForTagDecl = GlobalDeclID(); IdentifierInfo *TypedefNameForLinkage = nullptr; ///A flag to carry the information for a decl from the entity is @@ -124,15 +124,13 @@ namespace clang { return Record.readTypeSourceInfo(); } - serialization::DeclID readDeclID() { - return Record.readDeclID(); - } + GlobalDeclID readDeclID() { return Record.readDeclID(); } std::string readString() { return Record.readString(); } - void readDeclIDList(SmallVectorImpl &IDs) { + void readDeclIDList(SmallVectorImpl &IDs) { for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I) IDs.push_back(readDeclID()); } @@ -258,14 +256,14 @@ namespace clang { public: ASTDeclReader(ASTReader &Reader, ASTRecordReader &Record, - ASTReader::RecordLocation Loc, - DeclID thisDeclID, SourceLocation ThisDeclLoc) + ASTReader::RecordLocation Loc, GlobalDeclID thisDeclID, + SourceLocation ThisDeclLoc) : Reader(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID), ThisDeclLoc(ThisDeclLoc) {} - template static - void AddLazySpecializations(T *D, - SmallVectorImpl& IDs) { + template + static void AddLazySpecializations(T *D, + SmallVectorImpl &IDs) { if (IDs.empty()) return; @@ -275,13 +273,14 @@ namespace clang { auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; if (auto &Old = LazySpecializations) { - IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0]); + IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].get()); llvm::sort(IDs); IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); } - auto *Result = new (C) serialization::DeclID[1 + IDs.size()]; - *Result = IDs.size(); + auto *Result = new (C) GlobalDeclID[1 + IDs.size()]; + *Result = GlobalDeclID(IDs.size()); + std::copy(IDs.begin(), IDs.end(), Result + 1); LazySpecializations = Result; @@ -315,7 +314,7 @@ namespace clang { void ReadFunctionDefinition(FunctionDecl *FD); void Visit(Decl *D); - void UpdateDecl(Decl *D, SmallVectorImpl &); + void UpdateDecl(Decl *D, SmallVectorImpl &); static void setNextObjCCategory(ObjCCategoryDecl *Cat, ObjCCategoryDecl *Next) { @@ -557,7 +556,7 @@ void ASTDeclReader::Visit(Decl *D) { // If this is a tag declaration with a typedef name for linkage, it's safe // to load that typedef now. - if (NamedDeclForTagDecl) + if (NamedDeclForTagDecl.isValid()) cast(D)->TypedefNameDeclOrQualifier = cast(Reader.GetDecl(NamedDeclForTagDecl)); } else if (auto *ID = dyn_cast(D)) { @@ -601,8 +600,8 @@ void ASTDeclReader::VisitDecl(Decl *D) { // placeholder. GlobalDeclID SemaDCIDForTemplateParmDecl = readDeclID(); GlobalDeclID LexicalDCIDForTemplateParmDecl = - HasStandaloneLexicalDC ? readDeclID() : 0; - if (!LexicalDCIDForTemplateParmDecl) + HasStandaloneLexicalDC ? readDeclID() : GlobalDeclID(); + if (LexicalDCIDForTemplateParmDecl.isInvalid()) LexicalDCIDForTemplateParmDecl = SemaDCIDForTemplateParmDecl; Reader.addPendingDeclContextInfo(D, SemaDCIDForTemplateParmDecl, @@ -1848,7 +1847,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { // this namespace; loading it might load a later declaration of the // same namespace, and we have an invariant that older declarations // get merged before newer ones try to merge. - GlobalDeclID AnonNamespace = 0; + GlobalDeclID AnonNamespace; if (Redecl.getFirstID() == ThisDeclID) { AnonNamespace = readDeclID(); } else { @@ -1859,7 +1858,7 @@ void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) { mergeRedeclarable(D, Redecl); - if (AnonNamespace) { + if (AnonNamespace.isValid()) { // Each module has its own anonymous namespace, which is disjoint from // any other module's anonymous namespaces, so don't attach the anonymous // namespace at all. @@ -2019,7 +2018,7 @@ void ASTDeclReader::ReadCXXDefinitionData( if (Data.NumVBases) Data.VBases = ReadGlobalOffset(); - Data.FirstFriend = readDeclID(); + Data.FirstFriend = readDeclID().get(); } else { using Capture = LambdaCapture; @@ -2278,12 +2277,12 @@ ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) { // Lazily load the key function to avoid deserializing every method so we can // compute it. if (WasDefinition) { - DeclID KeyFn = readDeclID(); - if (KeyFn && D->isCompleteDefinition()) + GlobalDeclID KeyFn = readDeclID(); + if (KeyFn.get() && D->isCompleteDefinition()) // FIXME: This is wrong for the ARM ABI, where some other module may have // made this function no longer be a key function. We need an update // record or similar for that case. - C.KeyFunctions[D] = KeyFn; + C.KeyFunctions[D] = KeyFn.get(); } return Redecl; @@ -2372,7 +2371,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { for (unsigned i = 0; i != D->NumTPLists; ++i) D->getTrailingObjects()[i] = Record.readTemplateParameterList(); - D->NextFriend = readDeclID(); + D->NextFriend = readDeclID().get(); D->UnsupportedFriend = (Record.readInt() != 0); D->FriendLoc = readSourceLocation(); } @@ -2457,7 +2456,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. - SmallVector SpecIDs; + SmallVector SpecIDs; readDeclIDList(SpecIDs); ASTDeclReader::AddLazySpecializations(D, SpecIDs); } @@ -2485,7 +2484,7 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. - SmallVector SpecIDs; + SmallVector SpecIDs; readDeclIDList(SpecIDs); ASTDeclReader::AddLazySpecializations(D, SpecIDs); } @@ -2587,7 +2586,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This FunctionTemplateDecl owns a CommonPtr; read it. - SmallVector SpecIDs; + SmallVector SpecIDs; readDeclIDList(SpecIDs); ASTDeclReader::AddLazySpecializations(D, SpecIDs); } @@ -2783,7 +2782,7 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) { template ASTDeclReader::RedeclarableResult ASTDeclReader::VisitRedeclarable(Redeclarable *D) { - DeclID FirstDeclID = readDeclID(); + GlobalDeclID FirstDeclID = readDeclID(); Decl *MergeWith = nullptr; bool IsKeyDecl = ThisDeclID == FirstDeclID; @@ -2791,9 +2790,9 @@ ASTDeclReader::VisitRedeclarable(Redeclarable *D) { uint64_t RedeclOffset = 0; - // 0 indicates that this declaration was the only declaration of its entity, - // and is used for space optimization. - if (FirstDeclID == 0) { + // invalid FirstDeclID indicates that this declaration was the only + // declaration of its entity, and is used for space optimization. + if (FirstDeclID.isInvalid()) { FirstDeclID = ThisDeclID; IsKeyDecl = true; IsFirstLocalDecl = true; @@ -2922,9 +2921,9 @@ void ASTDeclReader::mergeTemplatePattern(RedeclarableTemplateDecl *D, bool IsKeyDecl) { auto *DPattern = D->getTemplatedDecl(); auto *ExistingPattern = Existing->getTemplatedDecl(); - RedeclarableResult Result(/*MergeWith*/ ExistingPattern, - DPattern->getCanonicalDecl()->getGlobalID(), - IsKeyDecl); + RedeclarableResult Result( + /*MergeWith*/ ExistingPattern, + GlobalDeclID(DPattern->getCanonicalDecl()->getGlobalID()), IsKeyDecl); if (auto *DClass = dyn_cast(DPattern)) { // Merge with any existing definition. @@ -3079,14 +3078,14 @@ void ASTDeclReader::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) { Expr *Init = Record.readExpr(); auto IK = static_cast(Record.readInt()); D->setInitializer(Init, IK); - D->PrevDeclInScope = readDeclID(); + D->PrevDeclInScope = readDeclID().get(); } void ASTDeclReader::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) { Record.readOMPChildren(D->Data); VisitValueDecl(D); D->VarName = Record.readDeclarationName(); - D->PrevDeclInScope = readDeclID(); + D->PrevDeclInScope = readDeclID().get(); } void ASTDeclReader::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) { @@ -3140,7 +3139,7 @@ public: OMPTraitInfo *readOMPTraitInfo() { return Reader.readOMPTraitInfo(); } - template T *GetLocalDeclAs(uint32_t LocalID) { + template T *GetLocalDeclAs(LocalDeclID LocalID) { return Reader.GetLocalDeclAs(LocalID); } }; @@ -3243,13 +3242,13 @@ bool ASTReader::isConsumerInterestedIn(Decl *D) { } /// Get the correct cursor and offset for loading a declaration. -ASTReader::RecordLocation -ASTReader::DeclCursorForID(DeclID ID, SourceLocation &Loc) { +ASTReader::RecordLocation ASTReader::DeclCursorForID(GlobalDeclID ID, + SourceLocation &Loc) { GlobalDeclMapType::iterator I = GlobalDeclMap.find(ID); assert(I != GlobalDeclMap.end() && "Corrupted global declaration map"); ModuleFile *M = I->second; const DeclOffset &DOffs = - M->DeclOffsets[ID - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; + M->DeclOffsets[ID.get() - M->BaseDeclID - NUM_PREDEF_DECL_IDS]; Loc = TranslateSourceLocation(*M, DOffs.getLocation()); return RecordLocation(M, DOffs.getBitOffset(M->DeclsBlockStartOffset)); } @@ -3792,8 +3791,8 @@ void ASTReader::markIncompleteDeclChain(Decl *D) { } /// Read the declaration at the given offset from the AST file. -Decl *ASTReader::ReadDeclRecord(DeclID ID) { - unsigned Index = ID - NUM_PREDEF_DECL_IDS; +Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { + unsigned Index = ID.get() - NUM_PREDEF_DECL_IDS; SourceLocation DeclLoc; RecordLocation Loc = DeclCursorForID(ID, DeclLoc); llvm::BitstreamCursor &DeclsCursor = Loc.F->DeclsCursor; @@ -3827,6 +3826,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { llvm::report_fatal_error( Twine("ASTReader::readDeclRecord failed reading decl code: ") + toString(MaybeDeclCode.takeError())); + switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: @@ -3953,9 +3953,8 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { } case DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK: { bool HasTypeConstraint = Record.readInt(); - D = NonTypeTemplateParmDecl::CreateDeserialized(Context, ID, - Record.readInt(), - HasTypeConstraint); + D = NonTypeTemplateParmDecl::CreateDeserialized( + Context, ID, Record.readInt(), HasTypeConstraint); break; } case DECL_TEMPLATE_TEMPLATE_PARM: @@ -4202,12 +4201,12 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { // The declaration may have been modified by files later in the chain. // If this is the case, read the record containing the updates from each file // and pass it to ASTDeclReader to make the modifications. - serialization::GlobalDeclID ID = Record.ID; + GlobalDeclID ID = Record.ID; Decl *D = Record.D; ProcessingUpdatesRAIIObj ProcessingUpdates(*this); DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); - SmallVector PendingLazySpecializationIDs; + SmallVector PendingLazySpecializationIDs; if (UpdI != DeclUpdateOffsets.end()) { auto UpdateOffsets = std::move(UpdI->second); @@ -4327,7 +4326,7 @@ void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { // we should instead generate one loop per kind and dispatch up-front? Decl *MostRecent = FirstLocal; for (unsigned I = 0, N = Record.size(); I != N; ++I) { - auto *D = GetLocalDecl(*M, Record[N - I - 1]); + auto *D = GetLocalDecl(*M, LocalDeclID(Record[N - I - 1])); ASTDeclReader::attachPreviousDecl(*this, D, MostRecent, CanonDecl); MostRecent = D; } @@ -4344,7 +4343,7 @@ namespace { llvm::SmallPtrSetImpl &Deserialized; ObjCCategoryDecl *Tail = nullptr; llvm::DenseMap NameCategoryMap; - serialization::GlobalDeclID InterfaceID; + GlobalDeclID InterfaceID; unsigned PreviousGeneration; void add(ObjCCategoryDecl *Cat) { @@ -4386,11 +4385,10 @@ namespace { } public: - ObjCCategoriesVisitor(ASTReader &Reader, - ObjCInterfaceDecl *Interface, - llvm::SmallPtrSetImpl &Deserialized, - serialization::GlobalDeclID InterfaceID, - unsigned PreviousGeneration) + ObjCCategoriesVisitor( + ASTReader &Reader, ObjCInterfaceDecl *Interface, + llvm::SmallPtrSetImpl &Deserialized, + GlobalDeclID InterfaceID, unsigned PreviousGeneration) : Reader(Reader), Interface(Interface), Deserialized(Deserialized), InterfaceID(InterfaceID), PreviousGeneration(PreviousGeneration) { // Populate the name -> category map with the set of known categories. @@ -4412,8 +4410,9 @@ namespace { // Map global ID of the definition down to the local ID used in this // module file. If there is no such mapping, we'll find nothing here // (or in any module it imports). - DeclID LocalID = Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); - if (!LocalID) + LocalDeclID LocalID = + Reader.mapGlobalIDToModuleFileGlobalID(M, InterfaceID); + if (LocalID.isInvalid()) return true; // Perform a binary search to find the local redeclarations for this @@ -4437,15 +4436,14 @@ namespace { M.ObjCCategories[Offset++] = 0; // Don't try to deserialize again for (unsigned I = 0; I != N; ++I) add(cast_or_null( - Reader.GetLocalDecl(M, M.ObjCCategories[Offset++]))); + Reader.GetLocalDecl(M, LocalDeclID(M.ObjCCategories[Offset++])))); return true; } }; } // namespace -void ASTReader::loadObjCCategories(serialization::GlobalDeclID ID, - ObjCInterfaceDecl *D, +void ASTReader::loadObjCCategories(GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration) { ObjCCategoriesVisitor Visitor(*this, D, CategoriesDeserialized, ID, PreviousGeneration); @@ -4473,8 +4471,9 @@ static void forAllLaterRedecls(DeclT *D, Fn F) { } } -void ASTDeclReader::UpdateDecl(Decl *D, - llvm::SmallVectorImpl &PendingLazySpecializationIDs) { +void ASTDeclReader::UpdateDecl( + Decl *D, + llvm::SmallVectorImpl &PendingLazySpecializationIDs) { while (Record.getIdx() < Record.size()) { switch ((DeclUpdateKind)Record.readInt()) { case UPD_CXX_ADDED_IMPLICIT_MEMBER: { diff --git a/clang/lib/Serialization/ASTReaderInternals.h b/clang/lib/Serialization/ASTReaderInternals.h index 25a46ddabcb7..49268ad5251d 100644 --- a/clang/lib/Serialization/ASTReaderInternals.h +++ b/clang/lib/Serialization/ASTReaderInternals.h @@ -49,15 +49,15 @@ public: static const int MaxTables = 4; /// The lookup result is a list of global declaration IDs. - using data_type = SmallVector; + using data_type = SmallVector; struct data_type_builder { data_type &Data; - llvm::DenseSet Found; + llvm::DenseSet Found; data_type_builder(data_type &D) : Data(D) {} - void insert(DeclID ID) { + void insert(GlobalDeclID ID) { // Just use a linear scan unless we have more than a few IDs. if (Found.empty() && !Data.empty()) { if (Data.size() <= 4) { @@ -108,7 +108,7 @@ public: static void MergeDataInto(const data_type &From, data_type_builder &To) { To.Data.reserve(To.Data.size() + From.size()); - for (DeclID ID : From) + for (GlobalDeclID ID : From) To.insert(ID); } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index baded0fe1983..7d3930022a69 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -956,14 +956,22 @@ void ASTStmtReader::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) { E->setRBracketLoc(readSourceLocation()); } -void ASTStmtReader::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { +void ASTStmtReader::VisitArraySectionExpr(ArraySectionExpr *E) { VisitExpr(E); + E->ASType = Record.readEnum(); + E->setBase(Record.readSubExpr()); E->setLowerBound(Record.readSubExpr()); E->setLength(Record.readSubExpr()); - E->setStride(Record.readSubExpr()); + + if (E->isOMPArraySection()) + E->setStride(Record.readSubExpr()); + E->setColonLocFirst(readSourceLocation()); - E->setColonLocSecond(readSourceLocation()); + + if (E->isOMPArraySection()) + E->setColonLocSecond(readSourceLocation()); + E->setRBracketLoc(readSourceLocation()); } @@ -3090,8 +3098,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = new (Context) MatrixSubscriptExpr(Empty); break; - case EXPR_OMP_ARRAY_SECTION: - S = new (Context) OMPArraySectionExpr(Empty); + case EXPR_ARRAY_SECTION: + S = new (Context) ArraySectionExpr(Empty); break; case EXPR_OMP_ARRAY_SHAPING: diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 018b854652a4..0408eeb6a95b 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -171,34 +171,9 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { .ModulesPruneNonAffectingModuleMaps) return std::nullopt; - SmallVector ModulesToProcess{RootModule}; - const HeaderSearch &HS = PP.getHeaderSearchInfo(); - - SmallVector FilesByUID; - HS.getFileMgr().GetUniqueIDMapping(FilesByUID); - - if (FilesByUID.size() > HS.header_file_size()) - FilesByUID.resize(HS.header_file_size()); - - for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { - OptionalFileEntryRef File = FilesByUID[UID]; - if (!File) - continue; - - const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(*File); - if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader)) - continue; - - for (const auto &KH : HS.findResolvedModulesForHeader(*File)) { - if (!KH.getModule()) - continue; - ModulesToProcess.push_back(KH.getModule()); - } - } - const ModuleMap &MM = HS.getModuleMap(); - SourceManager &SourceMgr = PP.getSourceManager(); + const SourceManager &SourceMgr = PP.getSourceManager(); std::set ModuleMaps; auto CollectIncludingModuleMaps = [&](FileID FID, FileEntryRef F) { @@ -233,12 +208,48 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { } }; - for (const Module *CurrentModule : ModulesToProcess) { + // Handle all the affecting modules referenced from the root module. + + std::queue Q; + Q.push(RootModule); + while (!Q.empty()) { + const Module *CurrentModule = Q.front(); + Q.pop(); + CollectIncludingMapsFromAncestors(CurrentModule); for (const Module *ImportedModule : CurrentModule->Imports) CollectIncludingMapsFromAncestors(ImportedModule); for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses) CollectIncludingMapsFromAncestors(UndeclaredModule); + + for (auto *M : CurrentModule->submodules()) + Q.push(M); + } + + // Handle textually-included headers that belong to other modules. + + SmallVector FilesByUID; + HS.getFileMgr().GetUniqueIDMapping(FilesByUID); + + if (FilesByUID.size() > HS.header_file_size()) + FilesByUID.resize(HS.header_file_size()); + + for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) { + OptionalFileEntryRef File = FilesByUID[UID]; + if (!File) + continue; + + const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(*File); + if (!HFI) + continue; // We have no information on this being a header file. + if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader) + continue; // Modular header, handled in the above module-based loop. + if (!HFI->isCompilingModuleHeader && !HFI->IsLocallyIncluded) + continue; // Non-modular header not included locally is not affecting. + + for (const auto &KH : HS.findResolvedModulesForHeader(*File)) + if (const Module *M = KH.getModule()) + CollectIncludingMapsFromAncestors(M); } return ModuleMaps; @@ -2053,14 +2064,13 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) { if (!File) continue; - // Get the file info. Skip emitting this file if we have no information on - // it as a header file (in which case HFI will be null) or if it hasn't - // changed since it was loaded. Also skip it if it's for a modular header - // from a different module; in that case, we rely on the module(s) - // containing the header to provide this information. const HeaderFileInfo *HFI = HS.getExistingLocalFileInfo(*File); - if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader)) - continue; + if (!HFI) + continue; // We have no information on this being a header file. + if (!HFI->isCompilingModuleHeader && HFI->isModuleHeader) + continue; // Header file info is tracked by the owning module file. + if (!HFI->isCompilingModuleHeader && !PP->alreadyIncluded(*File)) + continue; // Non-modular header not included is not needed. // Massage the file path into an appropriate form. StringRef Filename = File->getName(); @@ -3033,7 +3043,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule) { RecordData Inits; for (Decl *D : Context->getModuleInitializers(Mod)) if (wasDeclEmitted(D)) - Inits.push_back(GetDeclRef(D)); + AddDeclRef(D, Inits); if (!Inits.empty()) Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits); @@ -3210,13 +3220,13 @@ uint64_t ASTWriter::WriteDeclContextLexicalBlock(ASTContext &Context, return 0; uint64_t Offset = Stream.GetCurrentBitNo(); - SmallVector KindDeclPairs; + SmallVector KindDeclPairs; for (const auto *D : DC->decls()) { if (DoneWritingDeclsAndTypes && !wasDeclEmitted(D)) continue; KindDeclPairs.push_back(D->getKind()); - KindDeclPairs.push_back(GetDeclRef(D)); + KindDeclPairs.push_back(GetDeclRef(D).get()); } ++NumLexicalDeclContexts; @@ -3251,7 +3261,7 @@ void ASTWriter::WriteTypeDeclOffsets() { unsigned DeclOffsetAbbrev = Stream.EmitAbbrev(std::move(Abbrev)); { RecordData::value_type Record[] = {DECL_OFFSET, DeclOffsets.size(), - FirstDeclID - NUM_PREDEF_DECL_IDS}; + FirstDeclID.get() - NUM_PREDEF_DECL_IDS}; Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets)); } } @@ -3272,7 +3282,7 @@ void ASTWriter::WriteFileDeclIDsMap() { Info.FirstDeclIndex = FileGroupedDeclIDs.size(); llvm::stable_sort(Info.DeclIDs); for (auto &LocDeclEntry : Info.DeclIDs) - FileGroupedDeclIDs.push_back(LocDeclEntry.second); + FileGroupedDeclIDs.push_back(LocDeclEntry.second.get()); } auto Abbrev = std::make_shared(); @@ -3348,11 +3358,11 @@ public: for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - DataLen += 4; + DataLen += sizeof(DeclID); for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - DataLen += 4; + DataLen += sizeof(DeclID); return emitULEBKeyDataLength(KeyLen, DataLen, Out); } @@ -3410,11 +3420,11 @@ public: for (const ObjCMethodList *Method = &Methods.Instance; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); for (const ObjCMethodList *Method = &Methods.Factory; Method; Method = Method->getNext()) if (ShouldWriteMethodListNode(Method)) - LE.write(Writer.getDeclID(Method->getMethod())); + LE.write((DeclID)Writer.getDeclID(Method->getMethod())); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } @@ -3618,7 +3628,6 @@ class ASTIdentifierTableTrait { /// doesn't check whether the name has macros defined; use PublicMacroIterator /// to check that. bool isInterestingIdentifier(const IdentifierInfo *II, uint64_t MacroOffset) { - II->getObjCOrBuiltinID(); bool IsInteresting = II->getNotableIdentifierID() != tok::NotableIdentifierKind::not_notable || @@ -3687,7 +3696,8 @@ public: DataLen += 4; // MacroDirectives offset. if (NeedDecls) - DataLen += std::distance(IdResolver.begin(II), IdResolver.end()) * 4; + DataLen += std::distance(IdResolver.begin(II), IdResolver.end()) * + sizeof(DeclID); } return emitULEBKeyDataLength(KeyLen, DataLen, Out); } @@ -3733,8 +3743,8 @@ public: // Only emit declarations that aren't from a chained PCH, though. SmallVector Decls(IdResolver.decls(II)); for (NamedDecl *D : llvm::reverse(Decls)) - LE.write( - Writer.getDeclID(getDeclForLocalLookup(PP.getLangOpts(), D))); + LE.write((DeclID)Writer.getDeclID( + getDeclForLocalLookup(PP.getLangOpts(), D))); } } }; @@ -3850,7 +3860,7 @@ namespace { // Trait used for the on-disk hash table used in the method pool. class ASTDeclContextNameLookupTrait { ASTWriter &Writer; - llvm::SmallVector DeclIDs; + llvm::SmallVector DeclIDs; public: using key_type = DeclarationNameKey; @@ -3883,7 +3893,10 @@ public: data_type ImportData(const reader::ASTDeclContextNameLookupTrait::data_type &FromReader) { unsigned Start = DeclIDs.size(); - llvm::append_range(DeclIDs, FromReader); + DeclIDs.insert( + DeclIDs.end(), + DeclIDIterator(FromReader.begin()), + DeclIDIterator(FromReader.end())); return std::make_pair(Start, DeclIDs.size()); } @@ -3928,8 +3941,8 @@ public: break; } - // 4 bytes for each DeclID. - unsigned DataLen = 4 * (Lookup.second - Lookup.first); + // length of DeclIDs. + unsigned DataLen = sizeof(DeclID) * (Lookup.second - Lookup.first); return emitULEBKeyDataLength(KeyLen, DataLen, Out); } @@ -3972,7 +3985,7 @@ public: endian::Writer LE(Out, llvm::endianness::little); uint64_t Start = Out.tell(); (void)Start; for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) - LE.write(DeclIDs[I]); + LE.write((DeclID)DeclIDs[I]); assert(Out.tell() - Start == DataLen && "Data length is wrong"); } }; @@ -4306,7 +4319,8 @@ void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { DC = cast(Chain->getKeyDeclaration(cast(DC))); // Write the lookup table - RecordData::value_type Record[] = {UPDATE_VISIBLE, getDeclID(cast(DC))}; + RecordData::value_type Record[] = {UPDATE_VISIBLE, + getDeclID(cast(DC)).get()}; Stream.EmitRecordWithBlob(UpdateVisibleAbbrev, Record, LookupTable); } @@ -4360,7 +4374,7 @@ void ASTWriter::WriteObjCCategories() { Cat = Class->known_categories_begin(), CatEnd = Class->known_categories_end(); Cat != CatEnd; ++Cat, ++Size) { - assert(getDeclID(*Cat) != 0 && "Bogus category"); + assert(getDeclID(*Cat).isValid() && "Bogus category"); AddDeclRef(*Cat, Categories); } @@ -5078,7 +5092,7 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { if (!D || !wasDeclEmitted(D)) SemaDeclRefs.push_back(0); else - SemaDeclRefs.push_back(getDeclID(D)); + AddDeclRef(D, SemaDeclRefs); }; AddEmittedDeclRefOrZero(SemaRef.getStdNamespace()); @@ -5089,10 +5103,10 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) { Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); // Write the record containing decls to be checked for deferred diags. - SmallVector DeclsToCheckForDeferredDiags; + RecordData DeclsToCheckForDeferredDiags; for (auto *D : SemaRef.DeclsToCheckForDeferredDiags) if (wasDeclEmitted(D)) - DeclsToCheckForDeferredDiags.push_back(getDeclID(D)); + AddDeclRef(D, DeclsToCheckForDeferredDiags); if (!DeclsToCheckForDeferredDiags.empty()) Stream.EmitRecord(DECLS_TO_CHECK_FOR_DEFERRED_DIAGS, DeclsToCheckForDeferredDiags); @@ -5462,7 +5476,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { if (VisibleOffset) VisibleOffset -= DeclTypesBlockStartOffset; - DelayedNamespaceRecord.push_back(getDeclID(NS)); + AddDeclRef(NS, DelayedNamespaceRecord); DelayedNamespaceRecord.push_back(LexicalOffset); DelayedNamespaceRecord.push_back(VisibleOffset); } @@ -5486,7 +5500,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); // Create a lexical update block containing all of the declarations in the // translation unit that do not come from other AST files. - SmallVector NewGlobalKindDeclPairs; + SmallVector NewGlobalKindDeclPairs; for (const auto *D : TU->noload_decls()) { if (D->isFromASTFile()) continue; @@ -5496,7 +5510,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { continue; NewGlobalKindDeclPairs.push_back(D->getKind()); - NewGlobalKindDeclPairs.push_back(GetDeclRef(D)); + NewGlobalKindDeclPairs.push_back(GetDeclRef(D).get()); } auto Abv = std::make_shared(); @@ -5557,7 +5571,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: assert(Update.getDecl() && "no decl to add?"); - Record.push_back(GetDeclRef(Update.getDecl())); + Record.AddDeclRef(Update.getDecl()); break; case UPD_CXX_ADDED_FUNCTION_DEFINITION: @@ -5698,7 +5712,7 @@ void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) { } } - OffsetsRecord.push_back(GetDeclRef(D)); + AddDeclRef(D, OffsetsRecord); OffsetsRecord.push_back(Record.Emit(DECL_UPDATES)); } } @@ -5963,18 +5977,18 @@ void ASTWriter::AddEmittedDeclRef(const Decl *D, RecordDataImpl &Record) { if (!wasDeclEmitted(D)) return; - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } void ASTWriter::AddDeclRef(const Decl *D, RecordDataImpl &Record) { - Record.push_back(GetDeclRef(D)); + Record.push_back(GetDeclRef(D).get()); } -DeclID ASTWriter::GetDeclRef(const Decl *D) { +LocalDeclID ASTWriter::GetDeclRef(const Decl *D) { assert(WritingAST && "Cannot request a declaration ID before AST writing"); if (!D) { - return 0; + return LocalDeclID(); } // If the DeclUpdate from the GMF gets touched, emit it. @@ -5988,14 +6002,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(!(reinterpret_cast(D) & 0x01) && "Invalid decl pointer"); - DeclID &ID = DeclIDs[D]; - if (ID == 0) { + LocalDeclID &ID = DeclIDs[D]; + if (ID.isInvalid()) { if (DoneWritingDeclsAndTypes) { assert(0 && "New decl seen after serializing all the decls to emit!"); - return 0; + return LocalDeclID(); } // We haven't seen this declaration before. Give it a new ID and @@ -6007,14 +6021,14 @@ DeclID ASTWriter::GetDeclRef(const Decl *D) { return ID; } -DeclID ASTWriter::getDeclID(const Decl *D) { +LocalDeclID ASTWriter::getDeclID(const Decl *D) { if (!D) - return 0; + return LocalDeclID(); // If D comes from an AST file, its declaration ID is already known and // fixed. if (D->isFromASTFile()) - return D->getGlobalID(); + return LocalDeclID(D->getGlobalID()); assert(DeclIDs.contains(D) && "Declaration not emitted!"); return DeclIDs[D]; @@ -6035,8 +6049,8 @@ bool ASTWriter::wasDeclEmitted(const Decl *D) const { return Emitted; } -void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { - assert(ID); +void ASTWriter::associateDeclWithFile(const Decl *D, LocalDeclID ID) { + assert(ID.isValid()); assert(D); SourceLocation Loc = D->getLocation(); @@ -6068,7 +6082,7 @@ void ASTWriter::associateDeclWithFile(const Decl *D, DeclID ID) { if (!Info) Info = std::make_unique(); - std::pair LocDecl(Offset, ID); + std::pair LocDecl(Offset, ID); LocDeclIDsTy &Decls = Info->DeclIDs; Decls.push_back(LocDecl); } @@ -6338,7 +6352,7 @@ void ASTRecordWriter::AddCXXDefinitionData(const CXXRecordDecl *D) { Writer->Context->getLangOpts().ModulesDebugInfo && !D->isDependentType(); Record->push_back(ModulesDebugInfo); if (ModulesDebugInfo) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); + Writer->AddDeclRef(D, Writer->ModularCodegenDecls); // IsLambda bit is already saved. @@ -6442,7 +6456,7 @@ void ASTWriter::ReaderInitialized(ASTReader *Reader) { // Note, this will get called multiple times, once one the reader starts up // and again each time it's done reading a PCH or module. - FirstDeclID = NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls(); + FirstDeclID = LocalDeclID(NUM_PREDEF_DECL_IDS + Chain->getTotalNumDecls()); FirstTypeID = NUM_PREDEF_TYPE_IDS + Chain->getTotalNumTypes(); FirstIdentID = NUM_PREDEF_IDENT_IDS + Chain->getTotalNumIdentifiers(); FirstMacroID = NUM_PREDEF_MACRO_IDS + Chain->getTotalNumMacros(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index c6db107e0ca4..0edc4feda3ef 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -223,9 +223,9 @@ namespace clang { assert(!Common->LazySpecializations); } - ArrayRef LazySpecializations; + ArrayRef LazySpecializations; if (auto *LS = Common->LazySpecializations) - LazySpecializations = llvm::ArrayRef(LS + 1, LS[0]); + LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].get()); // Add a slot to the record for the number of specializations. unsigned I = Record.size(); @@ -243,7 +243,9 @@ namespace clang { assert(D->isCanonicalDecl() && "non-canonical decl in set"); AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); } - Record.append(LazySpecializations.begin(), LazySpecializations.end()); + Record.append( + DeclIDIterator(LazySpecializations.begin()), + DeclIDIterator(LazySpecializations.end())); // Update the size entry we added earlier. Record[I] = Record.size() - I - 1; @@ -1166,7 +1168,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { Record.push_back(VarDeclBits); if (ModulesCodegen) - Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D)); + Writer.AddDeclRef(D, Writer.ModularCodegenDecls); if (D->hasAttr()) { BlockVarCopyInit Init = Writer.Context->getBlockVarCopyInit(D); @@ -2786,10 +2788,10 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { "serializing"); // Determine the ID for this declaration. - serialization::DeclID ID; + LocalDeclID ID; assert(!D->isFromASTFile() && "should not be emitting imported decl"); - serialization::DeclID &IDR = DeclIDs[D]; - if (IDR == 0) + LocalDeclID &IDR = DeclIDs[D]; + if (IDR.isInvalid()) IDR = NextDeclID++; ID = IDR; @@ -2807,7 +2809,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Record the offset for this declaration SourceLocation Loc = D->getLocation(); - unsigned Index = ID - FirstDeclID; + unsigned Index = ID.get() - FirstDeclID.get(); if (DeclOffsets.size() == Index) DeclOffsets.emplace_back(getAdjustedLocation(Loc), Offset, DeclTypesBlockStartOffset); @@ -2827,7 +2829,7 @@ void ASTWriter::WriteDecl(ASTContext &Context, Decl *D) { // Note declarations that should be deserialized eagerly so that we can add // them to a record in the AST file later. if (isRequiredDecl(D, Context, WritingModule)) - EagerlyDeserializedDecls.push_back(ID); + AddDeclRef(D, EagerlyDeserializedDecls); } void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { @@ -2863,7 +2865,7 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { } Record->push_back(ModulesCodegen); if (ModulesCodegen) - Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(FD)); + Writer->AddDeclRef(FD, Writer->ModularCodegenDecls); if (auto *CD = dyn_cast(FD)) { Record->push_back(CD->getNumCtorInitializers()); if (CD->getNumCtorInitializers()) diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index cd5f733baf76..39aec31b6d87 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -880,16 +880,21 @@ void ASTStmtWriter::VisitMatrixSubscriptExpr(MatrixSubscriptExpr *E) { Code = serialization::EXPR_ARRAY_SUBSCRIPT; } -void ASTStmtWriter::VisitOMPArraySectionExpr(OMPArraySectionExpr *E) { +void ASTStmtWriter::VisitArraySectionExpr(ArraySectionExpr *E) { VisitExpr(E); + Record.writeEnum(E->ASType); Record.AddStmt(E->getBase()); Record.AddStmt(E->getLowerBound()); Record.AddStmt(E->getLength()); - Record.AddStmt(E->getStride()); + if (E->isOMPArraySection()) + Record.AddStmt(E->getStride()); Record.AddSourceLocation(E->getColonLocFirst()); - Record.AddSourceLocation(E->getColonLocSecond()); + + if (E->isOMPArraySection()) + Record.AddSourceLocation(E->getColonLocSecond()); + Record.AddSourceLocation(E->getRBracketLoc()); - Code = serialization::EXPR_OMP_ARRAY_SECTION; + Code = serialization::EXPR_ARRAY_SECTION; } void ASTStmtWriter::VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index a678c3827e7f..1cebfbbee77d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -188,9 +188,9 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State, os << DerefStr1; break; } - case Stmt::OMPArraySectionExprClass: { + case Stmt::ArraySectionExprClass: { os << "Array access"; - const OMPArraySectionExpr *AE = cast(S); + const ArraySectionExpr *AE = cast(S); AddDerefSource(os, Ranges, AE->getBase()->IgnoreParenCasts(), State.get(), N->getLocationContext()); os << DerefStr1; diff --git a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp index 1cf81b54e77d..7ac34ef8164e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp @@ -350,7 +350,7 @@ static bool isIdenticalStmt(const ASTContext &Ctx, const Stmt *Stmt1, return false; case Stmt::CallExprClass: case Stmt::ArraySubscriptExprClass: - case Stmt::OMPArraySectionExprClass: + case Stmt::ArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: case Stmt::OMPIteratorExprClass: case Stmt::ImplicitCastExprClass: diff --git a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp index bd495cd0f971..a0aa2316a7b4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp @@ -600,7 +600,7 @@ struct StreamOperationEvaluator { SValBuilder &SVB; const ASTContext &ACtx; - SymbolRef StreamSym; + SymbolRef StreamSym = nullptr; const StreamState *SS = nullptr; const CallExpr *CE = nullptr; StreamErrorState NewES; diff --git a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp index 4edb671753bf..6362c82b009d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/Taint.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/Taint.cpp @@ -216,21 +216,17 @@ std::vector taint::getTaintedSymbolsImpl(ProgramStateRef State, std::vector TaintedSymbols; if (!Reg) return TaintedSymbols; - // Element region (array element) is tainted if either the base or the offset - // are tainted. + + // Element region (array element) is tainted if the offset is tainted. if (const ElementRegion *ER = dyn_cast(Reg)) { std::vector TaintedIndex = getTaintedSymbolsImpl(State, ER->getIndex(), K, returnFirstOnly); llvm::append_range(TaintedSymbols, TaintedIndex); if (returnFirstOnly && !TaintedSymbols.empty()) return TaintedSymbols; // return early if needed - std::vector TaintedSuperRegion = - getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly); - llvm::append_range(TaintedSymbols, TaintedSuperRegion); - if (returnFirstOnly && !TaintedSymbols.empty()) - return TaintedSymbols; // return early if needed } + // Symbolic region is tainted if the corresponding symbol is tainted. if (const SymbolicRegion *SR = dyn_cast(Reg)) { std::vector TaintedRegions = getTaintedSymbolsImpl(State, SR->getSymbol(), K, returnFirstOnly); @@ -239,6 +235,8 @@ std::vector taint::getTaintedSymbolsImpl(ProgramStateRef State, return TaintedSymbols; // return early if needed } + // Any subregion (including Element and Symbolic regions) is tainted if its + // super-region is tainted. if (const SubRegion *ER = dyn_cast(Reg)) { std::vector TaintedSubRegions = getTaintedSymbolsImpl(State, ER->getSuperRegion(), K, returnFirstOnly); @@ -318,4 +316,4 @@ std::vector taint::getTaintedSymbolsImpl(ProgramStateRef State, } } return TaintedSymbols; -} \ No newline at end of file +} diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index 9ed8e7cab6ab..ec1db1cc3358 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -50,6 +50,9 @@ std::optional isUncounted(const clang::CXXRecordDecl* Class); /// class, false if not, std::nullopt if inconclusive. std::optional isUncountedPtr(const clang::Type* T); +/// \returns true if Name is a RefPtr, Ref, or its variant, false if not. +bool isRefType(const std::string &Name); + /// \returns true if \p F creates ref-countable object from uncounted parameter, /// false if not. bool isCtorOfRefCounted(const clang::FunctionDecl *F); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp index 8b41a949fd67..ae494de58da3 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedCallArgsChecker.cpp @@ -53,6 +53,13 @@ public: bool shouldVisitTemplateInstantiations() const { return true; } bool shouldVisitImplicitCode() const { return false; } + bool TraverseClassTemplateDecl(ClassTemplateDecl *Decl) { + if (isRefType(safeGetName(Decl))) + return true; + return RecursiveASTVisitor::TraverseClassTemplateDecl( + Decl); + } + bool VisitCallExpr(const CallExpr *CE) { Checker->visitCallExpr(CE); return true; diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 09c69f9612d9..0b1edf3e5c96 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1948,7 +1948,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::CXXPseudoDestructorExprClass: case Stmt::SubstNonTypeTemplateParmExprClass: case Stmt::CXXNullPtrLiteralExprClass: - case Stmt::OMPArraySectionExprClass: + case Stmt::ArraySectionExprClass: case Stmt::OMPArrayShapingExprClass: case Stmt::OMPIteratorExprClass: case Stmt::SYCLUniqueStableNameExprClass: diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp index 32850f5eea92..0c047b6c5da2 100644 --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -439,6 +439,9 @@ public: if (Result) setLastCC1Arguments(std::move(OriginalInvocation)); + // Propagate the statistics to the parent FileManager. + DriverFileMgr->AddStats(ScanInstance.getFileManager()); + return Result; } diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes index 5dbb83cab86b..b0eead42869a 100644 --- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes +++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes @@ -7,3 +7,7 @@ Tags: SwiftImportAs: reference SwiftReleaseOp: RCRelease SwiftRetainOp: RCRetain +- Name: NonCopyableType + SwiftCopyable: false +- Name: CopyableType + SwiftCopyable: true diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h index 82b8a6749c4f..a8f6d0248eae 100644 --- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h +++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h @@ -4,3 +4,6 @@ struct RefCountedType { int value; }; inline void RCRetain(RefCountedType *x) { x->value++; } inline void RCRelease(RefCountedType *x) { x->value--; } + +struct NonCopyableType { int value; }; +struct CopyableType { int value; }; diff --git a/clang/test/APINotes/swift-import-as.cpp b/clang/test/APINotes/swift-import-as.cpp index 904857e58593..103cf02f431a 100644 --- a/clang/test/APINotes/swift-import-as.cpp +++ b/clang/test/APINotes/swift-import-as.cpp @@ -2,6 +2,8 @@ // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter ImmortalRefType | FileCheck -check-prefix=CHECK-IMMORTAL %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter RefCountedType | FileCheck -check-prefix=CHECK-REF-COUNTED %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter NonCopyableType | FileCheck -check-prefix=CHECK-NON-COPYABLE %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %s #include @@ -14,3 +16,11 @@ // CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <> "import_reference" // CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <> "retain:RCRetain" // CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <> "release:RCRelease" + +// CHECK-NON-COPYABLE: Dumping NonCopyableType: +// CHECK-NON-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonCopyableType +// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <> "~Copyable" + +// CHECK-COPYABLE: Dumping CopyableType: +// CHECK-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct CopyableType +// CHECK-COPYABLE-NOT: SwiftAttrAttr diff --git a/clang/test/AST/Interp/c.c b/clang/test/AST/Interp/c.c index a5951158ed0e..207da5fe8126 100644 --- a/clang/test/AST/Interp/c.c +++ b/clang/test/AST/Interp/c.c @@ -263,3 +263,10 @@ const int *p = &b; const __int128 K = (__int128)(int*)0; const unsigned __int128 KU = (unsigned __int128)(int*)0; #endif + + +int test3(void) { + int a[2]; + a[0] = test3; // all-error {{incompatible pointer to integer conversion assigning to 'int' from 'int (void)'}} + return 0; +} diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp index f0325eef6d87..13cc9f43febc 100644 --- a/clang/test/AST/Interp/cxx23.cpp +++ b/clang/test/AST/Interp/cxx23.cpp @@ -141,3 +141,19 @@ struct check_ice { }; }; static_assert(check_ice<42>::x == 42); + + +namespace VirtualBases { + namespace One { + struct U { int n; }; + struct V : U { int n; }; + struct A : virtual V { int n; }; + struct Aa { int n; }; + struct B : virtual A, Aa {}; + struct C : virtual A, Aa {}; + struct D : B, C {}; + + /// Calls the constructor of D. + D d; + } +} diff --git a/clang/test/AST/Interp/functions.cpp b/clang/test/AST/Interp/functions.cpp index f9bb5d53634e..a5bb9f1a19aa 100644 --- a/clang/test/AST/Interp/functions.cpp +++ b/clang/test/AST/Interp/functions.cpp @@ -601,3 +601,19 @@ namespace FromIntegral { // both-warning {{variable length arrays}} #endif } + +namespace { + template using id = T; + template + constexpr void g() { + constexpr id f; + } + + static_assert((g(), true), ""); +} + +namespace { + /// The InitListExpr here is of void type. + void bir [[clang::annotate("B", {1, 2, 3, 4})]] (); // both-error {{'annotate' attribute requires parameter 1 to be a constant expression}} \ + // both-note {{subexpression not valid in a constant expression}} +} diff --git a/clang/test/AST/Interp/opencl.cl b/clang/test/AST/Interp/opencl.cl new file mode 100644 index 000000000000..b9ba4f8b9b55 --- /dev/null +++ b/clang/test/AST/Interp/opencl.cl @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -fsyntax-only -verify=ref,both %s +// RUN: %clang_cc1 -fsyntax-only -verify=expected,both %s -fexperimental-new-constant-interpreter + +// both-no-diagnostics + +typedef int int2 __attribute__((ext_vector_type(2))); +typedef int int3 __attribute__((ext_vector_type(3))); +typedef int int4 __attribute__((ext_vector_type(4))); +typedef int int8 __attribute__((ext_vector_type(8))); +typedef int int16 __attribute__((ext_vector_type(16))); + +void foo(int3 arg1, int8 arg2) { + int4 auto1; + int16 *auto2; + int auto3; + int2 auto4; + struct S *incomplete1; + + int res1[vec_step(arg1) == 4 ? 1 : -1]; + int res2[vec_step(arg2) == 8 ? 1 : -1]; + int res3[vec_step(auto1) == 4 ? 1 : -1]; + int res4[vec_step(*auto2) == 16 ? 1 : -1]; + int res5[vec_step(auto3) == 1 ? 1 : -1]; + int res6[vec_step(auto4) == 2 ? 1 : -1]; + int res7[vec_step(int2) == 2 ? 1 : -1]; + int res8[vec_step(int3) == 4 ? 1 : -1]; + int res9[vec_step(int4) == 4 ? 1 : -1]; + int res10[vec_step(int8) == 8 ? 1 : -1]; + int res11[vec_step(int16) == 16 ? 1 : -1]; + int res12[vec_step(void) == 1 ? 1 : -1]; +} + diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 3e52354a4a10..771e5adfca34 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -90,8 +90,7 @@ struct Ints2 { int a = 10; int b; }; -constexpr Ints2 ints22; // both-error {{without a user-provided default constructor}} \ - // expected-error {{must be initialized by a constant expression}} +constexpr Ints2 ints22; // both-error {{without a user-provided default constructor}} constexpr Ints2 I2 = Ints2{12, 25}; static_assert(I2.a == 12, ""); @@ -1031,6 +1030,12 @@ namespace ParenInit { // both-note {{required by 'constinit' specifier}} \ // both-note {{reference to temporary is not a constant expression}} \ // both-note {{temporary created here}} + + + /// Initializing an array. + constexpr void bar(int i, int j) { + int arr[4](i, j); + } } #endif @@ -1330,3 +1335,108 @@ namespace UnnamedBitFields { static_assert(a.f == 1.0, ""); static_assert(a.c == 'a', ""); } + +/// FIXME: This still doesn't work in the new interpreter because +/// we lack type information for dummy pointers. +namespace VirtualBases { + /// This used to crash. + namespace One { + class A { + protected: + int x; + }; + class B : public virtual A { + public: + int getX() { return x; } // ref-note {{declared here}} + }; + + class DV : virtual public B{}; + + void foo() { + DV b; + int a[b.getX()]; // both-warning {{variable length arrays}} \ + // ref-note {{non-constexpr function 'getX' cannot be used}} + } + } + + namespace Two { + struct U { int n; }; + struct A : virtual U { int n; }; + struct B : A {}; + B a; + static_assert((U*)(A*)(&a) == (U*)(&a), ""); + + struct C : virtual A {}; + struct D : B, C {}; + D d; + constexpr B *p = &d; + constexpr C *q = &d; + static_assert((A*)p == (A*)q, ""); // both-error {{failed}} + } + + namespace Three { + struct U { int n; }; + struct V : U { int n; }; + struct A : virtual V { int n; }; + struct Aa { int n; }; + struct B : virtual A, Aa {}; + + struct C : virtual A, Aa {}; + + struct D : B, C {}; + + D d; + + constexpr B *p = &d; + constexpr C *q = &d; + + static_assert((void*)p != (void*)q, ""); + static_assert((A*)p == (A*)q, ""); + static_assert((Aa*)p != (Aa*)q, ""); + + constexpr V *v = p; + constexpr V *w = q; + constexpr V *x = (A*)p; + static_assert(v == w, ""); + static_assert(v == x, ""); + + static_assert((U*)&d == p, ""); + static_assert((U*)&d == q, ""); + static_assert((U*)&d == v, ""); + static_assert((U*)&d == w, ""); + static_assert((U*)&d == x, ""); + + struct X {}; + struct Y1 : virtual X {}; + struct Y2 : X {}; + struct Z : Y1, Y2 {}; + Z z; + static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, ""); + } +} + +namespace ZeroInit { + struct S3 { + S3() = default; + S3(const S3&) = default; + S3(S3&&) = default; + constexpr S3(int n) : n(n) {} + int n; + }; + constexpr S3 s3d; // both-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}} + static_assert(s3d.n == 0, ""); +} + +namespace { +#if __cplusplus >= 202002L + struct C { + template constexpr C(const char (&)[N]) : n(N) {} + unsigned n; + }; + template + constexpr auto operator""_c() { return c.n; } + + constexpr auto waldo = "abc"_c; + static_assert(waldo == 4, ""); +#endif +} diff --git a/clang/test/AST/ast-dump-fpfeatures.cpp b/clang/test/AST/ast-dump-fpfeatures.cpp index da0011602a72..68144e31a930 100644 --- a/clang/test/AST/ast-dump-fpfeatures.cpp +++ b/clang/test/AST/ast-dump-fpfeatures.cpp @@ -1,10 +1,10 @@ // Test without serialization: -// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -ast-dump %s \ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -fcxx-exceptions -ast-dump %s \ // RUN: | FileCheck --strict-whitespace %s // Test with serialization: -// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -o %t %s -// RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -include-pch %t -ast-dump-all /dev/null \ +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -fcxx-exceptions -o %t %s +// RUN: %clang_cc1 -x c++ -triple x86_64-pc-linux -include-pch %t -fcxx-exceptions -ast-dump-all /dev/null \ // RUN: | sed -e "s/ //" -e "s/ imported//" \ // RUN: | FileCheck --strict-whitespace %s @@ -187,3 +187,65 @@ float func_18(float x, float y) { // CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward // CHECK: ReturnStmt // CHECK: BinaryOperator {{.*}} ConstRoundingMode=downward + +#pragma float_control(precise, off) + +__attribute__((optnone)) +float func_19(float x, float y) { + return x + y; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_19 'float (float, float)' +// CHECK: CompoundStmt {{.*}} MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +__attribute__((optnone)) +float func_20(float x, float y) try { + return x + y; +} catch (...) { + return 1.0; +} + +// CHECK-LABEL: FunctionDecl {{.*}} func_20 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +struct C21 { + C21(float x, float y); + __attribute__((optnone)) float a_method(float x, float y) { + return x * y; + } + float member; +}; + +// CHECK-LABEL: CXXMethodDecl {{.*}} a_method 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '*' ConstRoundingMode=downward MathErrno=1 + +__attribute__((optnone)) C21::C21(float x, float y) : member(x + y) {} + +// CHECK-LABEL: CXXConstructorDecl {{.*}} C21 'void (float, float)' +// CHECK: CXXCtorInitializer {{.*}} 'member' 'float' +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +template +__attribute__((optnone)) T func_22(T x, T y) { + return x + y; +} + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_22 +// CHECK: FunctionDecl {{.*}} func_22 'T (T, T)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} '+' ConstRoundingMode=downward MathErrno=1 +// CHECK: FunctionDecl {{.*}} func_22 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +float func_23(float x, float y) { + return func_22(x, y); +} \ No newline at end of file diff --git a/clang/test/AST/ast-dump-fpfeatures.m b/clang/test/AST/ast-dump-fpfeatures.m new file mode 100644 index 000000000000..cf77529a7568 --- /dev/null +++ b/clang/test/AST/ast-dump-fpfeatures.m @@ -0,0 +1,29 @@ +// Test without serialization: +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -ast-dump %s \ +// RUN: | FileCheck --strict-whitespace %s + +// Test with serialization: +// RUN: %clang_cc1 -triple x86_64-pc-linux -emit-pch -o %t %s +// RUN: %clang_cc1 -x objective-c -triple x86_64-pc-linux -include-pch %t -ast-dump-all /dev/null \ +// RUN: | sed -e "s/ //" -e "s/ imported//" \ +// RUN: | FileCheck --strict-whitespace %s + + +@interface Adder +- (float) sum: (float)x with: (float)y __attribute((optnone)); +@end + +#pragma float_control(precise, off) + +@implementation Adder +- (float) sum: (float)x with: (float)y __attribute((optnone)) { + return x + y; +} + +@end + +// CHECK-LABEL: ObjCImplementationDecl {{.*}} Adder +// CHECK: ObjCMethodDecl {{.*}} - sum:with: 'float' +// CHECK: CompoundStmt {{.*}} MathErrno=1 +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: BinaryOperator {{.*}} 'float' '+' MathErrno=1 diff --git a/clang/test/AST/ast-dump-late-parsing.cpp b/clang/test/AST/ast-dump-late-parsing.cpp new file mode 100644 index 000000000000..760664efc5f1 --- /dev/null +++ b/clang/test/AST/ast-dump-late-parsing.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-pc-linux -std=c++11 -fcxx-exceptions -fdelayed-template-parsing -ast-dump %s \ +// RUN: | FileCheck %s + +#pragma STDC FENV_ROUND FE_DOWNWARD +#pragma float_control(precise, off) + +template +__attribute__((optnone)) T func_22(T x, T y) { + return x + y; +} + +// CHECK-LABEL: FunctionTemplateDecl {{.*}} func_22 +// CHECK: FunctionDecl {{.*}} func_22 'T (T, T)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} '+' ConstRoundingMode=downward MathErrno=1 +// CHECK: FunctionDecl {{.*}} func_22 'float (float, float)' +// CHECK: CompoundStmt {{.*}} ConstRoundingMode=downward MathErrno=1 +// CHECK: ReturnStmt +// CHECK: BinaryOperator {{.*}} 'float' '+' ConstRoundingMode=downward MathErrno=1 + +float func_23(float x, float y) { + return func_22(x, y); +} diff --git a/clang/test/AST/ast-dump-macro-json.c b/clang/test/AST/ast-dump-macro-json.c index 96f4be6fec3d..fb9b4118b4f1 100644 --- a/clang/test/AST/ast-dump-macro-json.c +++ b/clang/test/AST/ast-dump-macro-json.c @@ -132,7 +132,7 @@ void BLAP(foo, __COUNTER__)(void); // CHECK-NEXT: "spellingLoc": { // CHECK-NEXT: "offset": {{[0-9]+}}, // CHECK-NEXT: "file": "", -// CHECK-NEXT: "line": 3, +// CHECK-NEXT: "line": 5, // CHECK-NEXT: "col": 1, // CHECK-NEXT: "tokLen": 4 // CHECK-NEXT: }, @@ -169,7 +169,7 @@ void BLAP(foo, __COUNTER__)(void); // CHECK-NEXT: "spellingLoc": { // CHECK-NEXT: "offset": {{[0-9]+}}, // CHECK-NEXT: "file": "", -// CHECK-NEXT: "line": 5, +// CHECK-NEXT: "line": 7, // CHECK-NEXT: "col": 1, // CHECK-NEXT: "tokLen": 4 // CHECK-NEXT: }, diff --git a/clang/test/AST/ast-dump-pragma-unroll.cpp b/clang/test/AST/ast-dump-pragma-unroll.cpp new file mode 100644 index 000000000000..f9c254b803ff --- /dev/null +++ b/clang/test/AST/ast-dump-pragma-unroll.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck %s + +using size_t = unsigned long long; + +// CHECK: LoopHintAttr {{.*}} Implicit unroll UnrollCount Numeric +// CHECK: LoopHintAttr {{.*}} Implicit unroll UnrollCount Numeric +// CHECK: LoopHintAttr {{.*}} Implicit unroll Unroll Disable +// CHECK: LoopHintAttr {{.*}} Implicit unroll Unroll Disable +template +int value_dependent(int n) { + constexpr int N = 100; + auto init = [=]() { return Flag ? n : 0UL; }; + auto cond = [=](size_t ix) { return Flag ? ix != 0 : ix < 10; }; + auto iter = [=](size_t ix) { + return Flag ? ix & ~(1ULL << __builtin_clzll(ix)) : ix + 1; + }; + +#pragma unroll Flag ? 1 : N + for (size_t ix = init(); cond(ix); ix = iter(ix)) { + n *= n; + } +#pragma unroll Flag ? 0 : N + for (size_t ix = init(); cond(ix); ix = iter(ix)) { + n *= n; + } + return n; +} + +void test_value_dependent(int n) { + value_dependent(n); +} diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index cfb013585ad7..77527743fe85 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -413,6 +413,14 @@ void RecoveryExprForInvalidDecls(Unknown InvalidDecl) { // CHECK-NEXT: `-RecoveryExpr {{.*}} '' } +void InitializerOfInvalidDecl() { + int ValidDecl; + Unkown InvalidDecl = ValidDecl; + // CHECK: VarDecl {{.*}} invalid InvalidDecl + // CHECK-NEXT: `-RecoveryExpr {{.*}} '' contains-errors + // CHECK-NEXT: `-DeclRefExpr {{.*}} 'int' lvalue Var {{.*}} 'ValidDecl' +} + void RecoverToAnInvalidDecl() { Unknown* foo; // invalid decl goo; // the typo was correct to the invalid foo. diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp index cf740516db6f..5ac55d269dce 100644 --- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp +++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp @@ -1846,6 +1846,42 @@ int main() // CHECK-NEXT: "kind": "VarTemplateDecl", // CHECK-NEXT: "name": "is_const_v" // CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "TemplateArgument", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const _Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "QualType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const _Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "qualifiers": "const", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmDecl", +// CHECK-NEXT: "name": "_Ty" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] @@ -1900,6 +1936,32 @@ int main() // CHECK-NEXT: "kind": "VarTemplateDecl", // CHECK-NEXT: "name": "is_reference_v" // CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "TemplateArgument", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmDecl", +// CHECK-NEXT: "name": "_Ty" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] @@ -2565,6 +2627,32 @@ int main() // CHECK-NEXT: "kind": "VarTemplateDecl", // CHECK-NEXT: "name": "is_function_v" // CHECK-NEXT: } +// CHECK-NEXT: ], +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "kind": "TemplateArgument", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty1" +// CHECK-NEXT: }, +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "_Ty1" +// CHECK-NEXT: }, +// CHECK-NEXT: "isDependent": true, +// CHECK-NEXT: "isInstantiationDependent": true, +// CHECK-NEXT: "depth": 0, +// CHECK-NEXT: "index": 0, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "TemplateTypeParmDecl", +// CHECK-NEXT: "name": "_Ty1" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp index d25ef36dd4d3..9fcafbcbcc46 100644 --- a/clang/test/AST/ast-dump-templates.cpp +++ b/clang/test/AST/ast-dump-templates.cpp @@ -104,3 +104,17 @@ void (*q)() = f<>; // CHECK1: template<> void f<0L>() // CHECK1: template<> void f<0U>() } + +namespace test6 { +template +constexpr bool C = true; + +template +void func() { + C; +// DUMP: UnresolvedLookupExpr {{.*}} '' lvalue (no ADL) = 'C' +// DUMP-NEXT: `-TemplateArgument type 'Key' +// DUMP-NEXT: `-TemplateTypeParmType {{.*}} 'Key' dependent depth 0 index 0 +// DUMP-NEXT: `-TemplateTypeParm {{.*}} 'Key' +} +} diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-regression-traverse-decl-crash.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-regression-traverse-decl-crash.cpp new file mode 100644 index 000000000000..3d8e822025f6 --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/call-args-regression-traverse-decl-crash.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s +// expected-no-diagnostics + +template struct T; +template