aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-12-18 20:11:37 +0000
commit461a67fa15370a9ec88f8f8a240bf7c123bb2029 (patch)
tree6942083d7d56bba40ec790a453ca58ad3baf6832 /lib
parent75c3240472ba6ac2669ee72ca67eb72d4e2851fc (diff)
downloadsrc-461a67fa15370a9ec88f8f8a240bf7c123bb2029.tar.gz
src-461a67fa15370a9ec88f8f8a240bf7c123bb2029.zip
Vendor import of clang trunk r321017:vendor/clang/clang-trunk-r321017
Notes
Notes: svn path=/vendor/clang/dist/; revision=326941 svn path=/vendor/clang/clang-trunk-r321017/; revision=326942; tag=vendor/clang/clang-trunk-r321017
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp687
-rw-r--r--lib/AST/ASTDumper.cpp157
-rw-r--r--lib/AST/ASTImporter.cpp601
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp15
-rw-r--r--lib/AST/CMakeLists.txt2
-rw-r--r--lib/AST/CXXABI.h13
-rw-r--r--lib/AST/CXXInheritance.cpp72
-rw-r--r--lib/AST/CommentSema.cpp10
-rw-r--r--lib/AST/DataCollection.cpp50
-rw-r--r--lib/AST/Decl.cpp634
-rw-r--r--lib/AST/DeclBase.cpp60
-rw-r--r--lib/AST/DeclCXX.cpp189
-rw-r--r--lib/AST/DeclFriend.cpp20
-rw-r--r--lib/AST/DeclGroup.cpp6
-rw-r--r--lib/AST/DeclObjC.cpp101
-rw-r--r--lib/AST/DeclPrinter.cpp181
-rw-r--r--lib/AST/DeclTemplate.cpp150
-rw-r--r--lib/AST/DeclarationName.cpp27
-rw-r--r--lib/AST/Expr.cpp116
-rw-r--r--lib/AST/ExprCXX.cpp233
-rw-r--r--lib/AST/ExprClassification.cpp3
-rw-r--r--lib/AST/ExprConstant.cpp139
-rw-r--r--lib/AST/ExprObjC.cpp12
-rw-r--r--lib/AST/ExternalASTMerger.cpp398
-rw-r--r--lib/AST/ExternalASTSource.cpp10
-rw-r--r--lib/AST/ItaniumCXXABI.cpp14
-rw-r--r--lib/AST/ItaniumMangle.cpp190
-rw-r--r--lib/AST/Linkage.h159
-rw-r--r--lib/AST/Mangle.cpp5
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp25
-rw-r--r--lib/AST/MicrosoftMangle.cpp27
-rw-r--r--lib/AST/NSAPI.cpp1
-rw-r--r--lib/AST/NestedNameSpecifier.cpp118
-rw-r--r--lib/AST/ODRHash.cpp67
-rw-r--r--lib/AST/OpenMPClause.cpp81
-rw-r--r--lib/AST/QualTypeNames.cpp (renamed from lib/Tooling/Core/QualTypeNames.cpp)13
-rw-r--r--lib/AST/RecordLayout.cpp9
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp38
-rw-r--r--lib/AST/Stmt.cpp78
-rw-r--r--lib/AST/StmtIterator.cpp17
-rw-r--r--lib/AST/StmtOpenMP.cpp49
-rw-r--r--lib/AST/StmtPrinter.cpp150
-rw-r--r--lib/AST/StmtProfile.cpp42
-rw-r--r--lib/AST/TemplateBase.cpp24
-rw-r--r--lib/AST/TemplateName.cpp32
-rw-r--r--lib/AST/Type.cpp304
-rw-r--r--lib/AST/TypeLoc.cpp131
-rw-r--r--lib/AST/TypePrinter.cpp154
-rw-r--r--lib/AST/VTTBuilder.cpp24
-rw-r--r--lib/AST/VTableBuilder.cpp21
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp5
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp329
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h120
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp43
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp60
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp38
-rw-r--r--lib/Analysis/BodyFarm.cpp366
-rw-r--r--lib/Analysis/BodyFarm.h51
-rw-r--r--lib/Analysis/CFG.cpp449
-rw-r--r--lib/Analysis/CallGraph.cpp38
-rw-r--r--lib/Analysis/CloneDetection.cpp155
-rw-r--r--lib/Analysis/CocoaConventions.cpp13
-rw-r--r--lib/Analysis/Consumed.cpp5
-rw-r--r--lib/Analysis/LiveVariables.cpp2
-rw-r--r--lib/Analysis/PrintfFormatString.cpp5
-rw-r--r--lib/Analysis/ReachableCode.cpp2
-rw-r--r--lib/Analysis/ScanfFormatString.cpp9
-rw-r--r--lib/Analysis/ThreadSafety.cpp21
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp11
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp1
-rw-r--r--lib/Analysis/UninitializedValues.cpp17
-rw-r--r--lib/Basic/Builtins.cpp10
-rw-r--r--lib/Basic/CMakeLists.txt56
-rw-r--r--lib/Basic/Cuda.cpp24
-rw-r--r--lib/Basic/Diagnostic.cpp7
-rw-r--r--lib/Basic/DiagnosticIDs.cpp46
-rw-r--r--lib/Basic/FileManager.cpp2
-rw-r--r--lib/Basic/IdentifierTable.cpp76
-rw-r--r--lib/Basic/Module.cpp30
-rw-r--r--lib/Basic/OpenMPKinds.cpp66
-rw-r--r--lib/Basic/OperatorPrecedence.cpp1
-rw-r--r--lib/Basic/SanitizerBlacklist.cpp27
-rw-r--r--lib/Basic/SanitizerSpecialCaseList.cpp64
-rw-r--r--lib/Basic/SourceManager.cpp66
-rw-r--r--lib/Basic/TargetInfo.cpp31
-rw-r--r--lib/Basic/Targets.cpp9511
-rw-r--r--lib/Basic/Targets.h51
-rw-r--r--lib/Basic/Targets/AArch64.cpp537
-rw-r--r--lib/Basic/Targets/AArch64.h167
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp373
-rw-r--r--lib/Basic/Targets/AMDGPU.h322
-rw-r--r--lib/Basic/Targets/ARM.cpp1064
-rw-r--r--lib/Basic/Targets/ARM.h256
-rw-r--r--lib/Basic/Targets/AVR.cpp320
-rw-r--r--lib/Basic/Targets/AVR.h184
-rw-r--r--lib/Basic/Targets/BPF.cpp25
-rw-r--r--lib/Basic/Targets/BPF.h94
-rw-r--r--lib/Basic/Targets/Hexagon.cpp158
-rw-r--r--lib/Basic/Targets/Hexagon.h128
-rw-r--r--lib/Basic/Targets/Lanai.cpp67
-rw-r--r--lib/Basic/Targets/Lanai.h92
-rw-r--r--lib/Basic/Targets/Le64.cpp39
-rw-r--r--lib/Basic/Targets/Le64.h64
-rw-r--r--lib/Basic/Targets/MSP430.cpp34
-rw-r--r--lib/Basic/Targets/MSP430.h92
-rw-r--r--lib/Basic/Targets/Mips.cpp252
-rw-r--r--lib/Basic/Targets/Mips.h397
-rw-r--r--lib/Basic/Targets/NVPTX.cpp199
-rw-r--r--lib/Basic/Targets/NVPTX.h132
-rw-r--r--lib/Basic/Targets/Nios2.cpp56
-rw-r--r--lib/Basic/Targets/Nios2.h147
-rw-r--r--lib/Basic/Targets/OSTargets.cpp139
-rw-r--r--lib/Basic/Targets/OSTargets.h725
-rw-r--r--lib/Basic/Targets/PNaCl.cpp30
-rw-r--r--lib/Basic/Targets/PNaCl.h87
-rw-r--r--lib/Basic/Targets/PPC.cpp544
-rw-r--r--lib/Basic/Targets/PPC.h368
-rw-r--r--lib/Basic/Targets/SPIR.cpp33
-rw-r--r--lib/Basic/Targets/SPIR.h127
-rw-r--r--lib/Basic/Targets/Sparc.cpp197
-rw-r--r--lib/Basic/Targets/Sparc.h270
-rw-r--r--lib/Basic/Targets/SystemZ.cpp118
-rw-r--r--lib/Basic/Targets/SystemZ.h145
-rw-r--r--lib/Basic/Targets/TCE.cpp35
-rw-r--r--lib/Basic/Targets/TCE.h123
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp96
-rw-r--r--lib/Basic/Targets/WebAssembly.h148
-rw-r--r--lib/Basic/Targets/X86.cpp1518
-rw-r--r--lib/Basic/Targets/X86.h801
-rw-r--r--lib/Basic/Targets/XCore.cpp38
-rw-r--r--lib/Basic/Targets/XCore.h82
-rw-r--r--lib/Basic/Version.cpp2
-rw-r--r--lib/Basic/VirtualFileSystem.cpp57
-rw-r--r--lib/Basic/XRayLists.cpp14
-rw-r--r--lib/CMakeLists.txt1
-rw-r--r--lib/CodeGen/BackendUtil.cpp121
-rw-r--r--lib/CodeGen/CGAtomic.cpp306
-rw-r--r--lib/CodeGen/CGBlocks.cpp335
-rw-r--r--lib/CodeGen/CGBuilder.h7
-rw-r--r--lib/CodeGen/CGBuiltin.cpp1521
-rw-r--r--lib/CodeGen/CGCXX.cpp32
-rw-r--r--lib/CodeGen/CGCXXABI.cpp11
-rw-r--r--lib/CodeGen/CGCXXABI.h21
-rw-r--r--lib/CodeGen/CGCall.cpp93
-rw-r--r--lib/CodeGen/CGClass.cpp177
-rw-r--r--lib/CodeGen/CGCleanup.cpp2
-rw-r--r--lib/CodeGen/CGCoroutine.cpp11
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp157
-rw-r--r--lib/CodeGen/CGDebugInfo.h11
-rw-r--r--lib/CodeGen/CGDecl.cpp42
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp89
-rw-r--r--lib/CodeGen/CGException.cpp45
-rw-r--r--lib/CodeGen/CGExpr.cpp741
-rw-r--r--lib/CodeGen/CGExprAgg.cpp19
-rw-r--r--lib/CodeGen/CGExprCXX.cpp108
-rw-r--r--lib/CodeGen/CGExprComplex.cpp32
-rw-r--r--lib/CodeGen/CGExprConstant.cpp1237
-rw-r--r--lib/CodeGen/CGExprScalar.cpp135
-rw-r--r--lib/CodeGen/CGObjC.cpp36
-rw-r--r--lib/CodeGen/CGObjCMac.cpp27
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp3
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp71
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.h21
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp860
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h106
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp362
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.h31
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp37
-rw-r--r--lib/CodeGen/CGStmt.cpp50
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp964
-rw-r--r--lib/CodeGen/CGVTT.cpp2
-rw-r--r--lib/CodeGen/CGVTables.cpp38
-rw-r--r--lib/CodeGen/CGValue.h70
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp7
-rw-r--r--lib/CodeGen/CodeGenAction.cpp65
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp228
-rw-r--r--lib/CodeGen/CodeGenFunction.h280
-rw-r--r--lib/CodeGen/CodeGenModule.cpp390
-rw-r--r--lib/CodeGen/CodeGenModule.h100
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp173
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp265
-rw-r--r--lib/CodeGen/CodeGenTBAA.h200
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h5
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp16
-rw-r--r--lib/CodeGen/CodeGenTypes.h5
-rw-r--r--lib/CodeGen/ConstantEmitter.h178
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp368
-rw-r--r--lib/CodeGen/CoverageMappingGen.h2
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp110
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp116
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp13
-rw-r--r--lib/CodeGen/SanitizerMetadata.cpp9
-rw-r--r--lib/CodeGen/TargetInfo.cpp641
-rw-r--r--lib/CodeGen/TargetInfo.h60
-rw-r--r--lib/CrossTU/CMakeLists.txt13
-rw-r--r--lib/CrossTU/CrossTranslationUnit.cpp269
-rw-r--r--lib/Driver/CMakeLists.txt1
-rw-r--r--lib/Driver/Compilation.cpp97
-rw-r--r--lib/Driver/Distro.cpp6
-rw-r--r--lib/Driver/Driver.cpp147
-rw-r--r--lib/Driver/DriverOptions.cpp11
-rw-r--r--lib/Driver/Job.cpp11
-rw-r--r--lib/Driver/SanitizerArgs.cpp166
-rw-r--r--lib/Driver/ToolChain.cpp212
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp60
-rw-r--r--lib/Driver/ToolChains/AMDGPU.h20
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp22
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp50
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp102
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h4
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp12
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h1
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp2
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp5
-rw-r--r--lib/Driver/ToolChains/BareMetal.h1
-rw-r--r--lib/Driver/ToolChains/Bitrig.cpp190
-rw-r--r--lib/Driver/ToolChains/Bitrig.h79
-rw-r--r--lib/Driver/ToolChains/Clang.cpp2426
-rw-r--r--lib/Driver/ToolChains/Clang.h4
-rw-r--r--lib/Driver/ToolChains/CloudABI.cpp4
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp238
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h7
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp45
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp281
-rw-r--r--lib/Driver/ToolChains/Cuda.h28
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp760
-rw-r--r--lib/Driver/ToolChains/Darwin.h79
-rw-r--r--lib/Driver/ToolChains/DragonFly.cpp3
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp14
-rw-r--r--lib/Driver/ToolChains/FreeBSD.h3
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp44
-rw-r--r--lib/Driver/ToolChains/Fuchsia.h7
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp221
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp98
-rw-r--r--lib/Driver/ToolChains/Hexagon.h4
-rw-r--r--lib/Driver/ToolChains/Linux.cpp26
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp47
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp43
-rw-r--r--lib/Driver/ToolChains/MinGW.h4
-rw-r--r--lib/Driver/ToolChains/Minix.cpp3
-rw-r--r--lib/Driver/ToolChains/NaCl.cpp16
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp30
-rw-r--r--lib/Driver/ToolChains/NetBSD.h3
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp3
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp3
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp2
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp45
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h2
-rw-r--r--lib/Driver/XRayArgs.cpp18
-rw-r--r--lib/Format/BreakableToken.cpp542
-rw-r--r--lib/Format/BreakableToken.h317
-rw-r--r--lib/Format/ContinuationIndenter.cpp747
-rw-r--r--lib/Format/ContinuationIndenter.h75
-rw-r--r--lib/Format/Format.cpp195
-rw-r--r--lib/Format/FormatInternal.h83
-rw-r--r--lib/Format/FormatToken.cpp6
-rw-r--r--lib/Format/FormatToken.h167
-rw-r--r--lib/Format/FormatTokenLexer.cpp88
-rw-r--r--lib/Format/FormatTokenLexer.h4
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp10
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.h2
-rw-r--r--lib/Format/SortJavaScriptImports.cpp16
-rw-r--r--lib/Format/TokenAnalyzer.cpp40
-rw-r--r--lib/Format/TokenAnalyzer.h47
-rw-r--r--lib/Format/TokenAnnotator.cpp265
-rw-r--r--lib/Format/TokenAnnotator.h5
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp259
-rw-r--r--lib/Format/UnwrappedLineFormatter.h11
-rw-r--r--lib/Format/UnwrappedLineParser.cpp320
-rw-r--r--lib/Format/UnwrappedLineParser.h43
-rw-r--r--lib/Format/UsingDeclarationsSorter.cpp91
-rw-r--r--lib/Format/UsingDeclarationsSorter.h2
-rw-r--r--lib/Format/WhitespaceManager.cpp33
-rw-r--r--lib/Format/WhitespaceManager.h8
-rw-r--r--lib/Frontend/ASTUnit.cpp64
-rw-r--r--lib/Frontend/CompilerInstance.cpp74
-rw-r--r--lib/Frontend/CompilerInvocation.cpp168
-rw-r--r--lib/Frontend/FrontendAction.cpp23
-rw-r--r--lib/Frontend/FrontendActions.cpp26
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp1
-rw-r--r--lib/Frontend/InitPreprocessor.cpp108
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp32
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp261
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp24
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp2
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp2
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp2
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp37
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp143
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp17
-rw-r--r--lib/Headers/CMakeLists.txt12
-rw-r--r--lib/Headers/__clang_cuda_cmath.h23
-rw-r--r--lib/Headers/__clang_cuda_intrinsics.h146
-rw-r--r--lib/Headers/__clang_cuda_math_forward_declares.h8
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h36
-rw-r--r--lib/Headers/arm64intr.h49
-rw-r--r--lib/Headers/avx2intrin.h12
-rw-r--r--lib/Headers/avx512bwintrin.h562
-rw-r--r--lib/Headers/avx512cdintrin.h5
-rw-r--r--lib/Headers/avx512dqintrin.h38
-rw-r--r--lib/Headers/avx512fintrin.h675
-rw-r--r--lib/Headers/avx512vlbwintrin.h1019
-rw-r--r--lib/Headers/avx512vlcdintrin.h10
-rw-r--r--lib/Headers/avx512vldqintrin.h54
-rw-r--r--lib/Headers/avx512vlintrin.h1024
-rw-r--r--lib/Headers/avx512vpopcntdqvlintrin.h99
-rw-r--r--lib/Headers/cetintrin.h93
-rw-r--r--lib/Headers/clflushoptintrin.h2
-rw-r--r--lib/Headers/clwbintrin.h52
-rw-r--r--lib/Headers/cuda_wrappers/algorithm2
-rw-r--r--lib/Headers/cuda_wrappers/new51
-rw-r--r--lib/Headers/emmintrin.h12
-rw-r--r--lib/Headers/float.h14
-rw-r--r--lib/Headers/fma4intrin.h44
-rw-r--r--lib/Headers/fmaintrin.h48
-rw-r--r--lib/Headers/immintrin.h13
-rw-r--r--lib/Headers/intrin.h6
-rw-r--r--lib/Headers/opencl-c.h666
-rw-r--r--lib/Headers/stdbool.h5
-rw-r--r--lib/Headers/unwind.h80
-rw-r--r--lib/Index/CodegenNameGenerator.cpp39
-rw-r--r--lib/Index/CommentToXML.cpp1
-rw-r--r--lib/Index/IndexBody.cpp11
-rw-r--r--lib/Index/IndexDecl.cpp36
-rw-r--r--lib/Index/IndexSymbol.cpp38
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp13
-rw-r--r--lib/Index/IndexingAction.cpp22
-rw-r--r--lib/Index/IndexingContext.cpp4
-rw-r--r--lib/Index/USRGeneration.cpp74
-rw-r--r--lib/Lex/HeaderSearch.cpp91
-rw-r--r--lib/Lex/Lexer.cpp465
-rw-r--r--lib/Lex/LiteralSupport.cpp57
-rw-r--r--lib/Lex/MacroArgs.cpp51
-rw-r--r--lib/Lex/MacroInfo.cpp36
-rw-r--r--lib/Lex/ModuleMap.cpp148
-rw-r--r--lib/Lex/PPDirectives.cpp206
-rw-r--r--lib/Lex/PPLexerChange.cpp7
-rw-r--r--lib/Lex/PPMacroExpansion.cpp144
-rw-r--r--lib/Lex/PTHLexer.cpp89
-rw-r--r--lib/Lex/Pragma.cpp54
-rw-r--r--lib/Lex/PreprocessingRecord.cpp49
-rw-r--r--lib/Lex/Preprocessor.cpp95
-rw-r--r--lib/Lex/PreprocessorLexer.cpp11
-rw-r--r--lib/Lex/TokenConcatenation.cpp10
-rw-r--r--lib/Lex/TokenLexer.cpp296
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp3
-rw-r--r--lib/Parse/ParseDecl.cpp160
-rw-r--r--lib/Parse/ParseDeclCXX.cpp72
-rw-r--r--lib/Parse/ParseExpr.cpp35
-rw-r--r--lib/Parse/ParseExprCXX.cpp58
-rw-r--r--lib/Parse/ParseObjc.cpp28
-rw-r--r--lib/Parse/ParseOpenMP.cpp146
-rw-r--r--lib/Parse/ParsePragma.cpp12
-rw-r--r--lib/Parse/ParseStmt.cpp24
-rw-r--r--lib/Parse/ParseStmtAsm.cpp235
-rw-r--r--lib/Parse/ParseTemplate.cpp36
-rw-r--r--lib/Parse/ParseTentative.cpp5
-rw-r--r--lib/Parse/Parser.cpp41
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp5
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp38
-rw-r--r--lib/Sema/AttributeList.cpp5
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp28
-rw-r--r--lib/Sema/DeclSpec.cpp14
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp2
-rw-r--r--lib/Sema/Sema.cpp185
-rw-r--r--lib/Sema/SemaAttr.cpp69
-rw-r--r--lib/Sema/SemaCast.cpp19
-rw-r--r--lib/Sema/SemaChecking.cpp1265
-rw-r--r--lib/Sema/SemaCodeComplete.cpp124
-rw-r--r--lib/Sema/SemaCoroutine.cpp51
-rw-r--r--lib/Sema/SemaDecl.cpp709
-rw-r--r--lib/Sema/SemaDeclAttr.cpp407
-rw-r--r--lib/Sema/SemaDeclCXX.cpp777
-rw-r--r--lib/Sema/SemaDeclObjC.cpp212
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp14
-rw-r--r--lib/Sema/SemaExpr.cpp693
-rw-r--r--lib/Sema/SemaExprCXX.cpp124
-rw-r--r--lib/Sema/SemaExprMember.cpp65
-rw-r--r--lib/Sema/SemaExprObjC.cpp49
-rw-r--r--lib/Sema/SemaInit.cpp164
-rw-r--r--lib/Sema/SemaLambda.cpp47
-rw-r--r--lib/Sema/SemaLookup.cpp107
-rw-r--r--lib/Sema/SemaObjCProperty.cpp16
-rw-r--r--lib/Sema/SemaOpenMP.cpp1971
-rw-r--r--lib/Sema/SemaOverload.cpp322
-rw-r--r--lib/Sema/SemaPseudoObject.cpp3
-rw-r--r--lib/Sema/SemaStmt.cpp83
-rw-r--r--lib/Sema/SemaStmtAsm.cpp83
-rw-r--r--lib/Sema/SemaStmtAttr.cpp12
-rw-r--r--lib/Sema/SemaTemplate.cpp144
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp182
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp38
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp110
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp183
-rw-r--r--lib/Sema/SemaType.cpp519
-rw-r--r--lib/Sema/TreeTransform.h155
-rw-r--r--lib/Serialization/ASTCommon.cpp3
-rw-r--r--lib/Serialization/ASTCommon.h3
-rw-r--r--lib/Serialization/ASTReader.cpp688
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp90
-rw-r--r--lib/Serialization/ASTReaderInternals.h92
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp46
-rw-r--r--lib/Serialization/ASTWriter.cpp250
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp83
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp26
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp4
-rw-r--r--lib/Serialization/ModuleManager.cpp59
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h69
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp54
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt2
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp43
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/CloneChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/ConversionChecker.cpp57
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp33
-rw-r--r--lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp153
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp32
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp19
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp73
-rw-r--r--lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp140
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp35
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp148
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp314
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp51
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp453
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp43
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp85
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp96
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt2
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp34
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp32
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp142
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp64
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp314
-rw-r--r--lib/StaticAnalyzer/Core/IssueHash.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/LoopUnrolling.cpp294
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp13
-rw-r--r--lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h2
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp107
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp44
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp27
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp12
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp3
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp1021
-rw-r--r--lib/Tooling/ASTDiff/CMakeLists.txt11
-rw-r--r--lib/Tooling/ArgumentsAdjusters.cpp14
-rw-r--r--lib/Tooling/CMakeLists.txt3
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp122
-rw-r--r--lib/Tooling/CompilationDatabase.cpp53
-rw-r--r--lib/Tooling/Core/CMakeLists.txt1
-rw-r--r--lib/Tooling/Core/Replacement.cpp2
-rw-r--r--lib/Tooling/Execution.cpp105
-rw-r--r--lib/Tooling/Refactoring/ASTSelection.cpp453
-rw-r--r--lib/Tooling/Refactoring/ASTSelectionRequirements.cpp48
-rw-r--r--lib/Tooling/Refactoring/AtomicChange.cpp188
-rw-r--r--lib/Tooling/Refactoring/CMakeLists.txt13
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp199
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.cpp112
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.h52
-rw-r--r--lib/Tooling/Refactoring/RefactoringActions.cpp114
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp197
-rw-r--r--lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp37
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFindingAction.cpp54
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp298
-rw-r--r--lib/Tooling/StandaloneExecution.cpp91
-rw-r--r--lib/Tooling/Tooling.cpp16
486 files changed, 47816 insertions, 26475 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c60373c5a90a..dd96148edb27 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1,4 +1,4 @@
-//===--- ASTContext.cpp - Context to hold long-lived AST nodes ------------===//
+//===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,33 +13,83 @@
#include "clang/AST/ASTContext.h"
#include "CXXABI.h"
+#include "clang/AST/APValue.h"
#include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/AttrIterator.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Comment.h"
-#include "clang/AST/CommentCommandTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/MangleNumberingContext.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/RawCommentList.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/UnresolvedSet.h"
#include "clang/AST/VTableBuilder.h"
+#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Linkage.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/XRayLists.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/Capacity.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
#include <map>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <utility>
using namespace clang;
@@ -57,7 +107,7 @@ unsigned ASTContext::NumImplicitDestructors;
unsigned ASTContext::NumImplicitDestructorsDeclared;
enum FloatingRank {
- HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
+ Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
@@ -256,11 +306,10 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
return *Comment;
}
-namespace {
/// If we have a 'templated' declaration for a template, adjust 'D' to
/// refer to the actual template.
/// If we have an implicit instantiation, adjust 'D' to refer to template.
-const Decl *adjustDeclToTemplate(const Decl *D) {
+static const Decl *adjustDeclToTemplate(const Decl *D) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// Is this function declaration part of a function template?
if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
@@ -327,7 +376,6 @@ const Decl *adjustDeclToTemplate(const Decl *D) {
// FIXME: Adjust alias templates?
return D;
}
-} // anonymous namespace
const RawComment *ASTContext::getRawCommentForAnyRedecl(
const Decl *D,
@@ -697,8 +745,8 @@ CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
llvm_unreachable("Invalid CXXABI type!");
}
-static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,
- const LangOptions &LOpts) {
+static const LangASMap *getAddressSpaceMap(const TargetInfo &T,
+ const LangOptions &LOpts) {
if (LOpts.FakeAddressSpaceMap) {
// The fake address space map must have a distinct entry for each
// language-specific address space.
@@ -707,6 +755,7 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,
1, // opencl_global
3, // opencl_local
2, // opencl_constant
+ 0, // opencl_private
4, // opencl_generic
5, // cuda_device
6, // cuda_constant
@@ -736,25 +785,12 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
Builtin::Context &builtins)
: FunctionProtoTypes(this_()), TemplateSpecializationTypes(this_()),
DependentTemplateSpecializationTypes(this_()),
- SubstTemplateTemplateParmPacks(this_()),
- GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr),
- UInt128Decl(nullptr), BuiltinVaListDecl(nullptr),
- BuiltinMSVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr),
- ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
- CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr),
- ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr),
- sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
- BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr),
- cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(),
- ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr),
- TypePackElementDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
+ SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
LangOpts.XRayNeverInstrumentFiles, SM)),
- AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
- BuiltinInfo(builtins), DeclarationNames(*this), ExternalSource(nullptr),
- Listener(nullptr), Comments(SM), CommentsLoaded(false),
+ BuiltinInfo(builtins), DeclarationNames(*this), Comments(SM),
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
}
@@ -1093,6 +1129,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// GNU extension, __float128 for IEEE quadruple precision
InitBuiltinType(Float128Ty, BuiltinType::Float128);
+ // C11 extension ISO/IEC TS 18661-3
+ InitBuiltinType(Float16Ty, BuiltinType::Float16);
+
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
@@ -1182,7 +1221,14 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
ObjCSuperType = QualType();
// void * type
- VoidPtrTy = getPointerType(VoidTy);
+ if (LangOpts.OpenCLVersion >= 200) {
+ auto Q = VoidTy.getQualifiers();
+ Q.setAddressSpace(LangAS::opencl_generic);
+ VoidPtrTy = getPointerType(getCanonicalType(
+ getQualifiedType(VoidTy.getUnqualifiedType(), Q)));
+ } else {
+ VoidPtrTy = getPointerType(VoidTy);
+ }
// nullptr type (C++0x 2.14.7)
InitBuiltinType(NullPtrTy, BuiltinType::NullPtr);
@@ -1209,7 +1255,7 @@ AttrVec& ASTContext::getDeclAttrs(const Decl *D) {
}
/// \brief Erase the attributes corresponding to the given declaration.
-void ASTContext::eraseDeclAttrs(const Decl *D) {
+void ASTContext::eraseDeclAttrs(const Decl *D) {
llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);
if (Pos != DeclAttrs.end()) {
Pos->second->~AttrVec();
@@ -1332,35 +1378,27 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst,
ASTContext::overridden_cxx_method_iterator
ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return nullptr;
- return Pos->second.begin();
+ return overridden_methods(Method).begin();
}
ASTContext::overridden_cxx_method_iterator
ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return nullptr;
- return Pos->second.end();
+ return overridden_methods(Method).end();
}
unsigned
ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
- llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
- OverriddenMethods.find(Method->getCanonicalDecl());
- if (Pos == OverriddenMethods.end())
- return 0;
- return Pos->second.size();
+ auto Range = overridden_methods(Method);
+ return Range.end() - Range.begin();
}
ASTContext::overridden_method_range
ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
- return overridden_method_range(overridden_methods_begin(Method),
- overridden_methods_end(Method));
+ llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos =
+ OverriddenMethods.find(Method->getCanonicalDecl());
+ if (Pos == OverriddenMethods.end())
+ return overridden_method_range(nullptr, nullptr);
+ return overridden_method_range(Pos->second.begin(), Pos->second.end());
}
void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
@@ -1413,7 +1451,9 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
assert(BT && "Not a floating point type!");
switch (BT->getKind()) {
default: llvm_unreachable("Not a floating point type!");
- case BuiltinType::Half: return Target->getHalfFormat();
+ case BuiltinType::Float16:
+ case BuiltinType::Half:
+ return Target->getHalfFormat();
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
case BuiltinType::LongDouble: return Target->getLongDoubleFormat();
@@ -1450,7 +1490,6 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
// else about the declaration and its type.
if (UseAlignAttrOnly) {
// do nothing
-
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
@@ -1624,6 +1663,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
uint64_t Width = 0;
unsigned Align = 8;
bool AlignIsRequired = false;
+ unsigned AS = 0;
switch (T->getTypeClass()) {
#define TYPE(Class, Base)
#define ABSTRACT_TYPE(Class, Base)
@@ -1690,7 +1730,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 0;
Align = 8;
break;
-
case BuiltinType::Bool:
Width = Target->getBoolWidth();
Align = Target->getBoolAlign();
@@ -1740,6 +1779,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 128;
Align = 128; // int128_t is 128-bit aligned on all targets.
break;
+ case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
Align = Target->getHalfAlign();
@@ -1770,60 +1810,48 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Target->getPointerWidth(0);
Align = Target->getPointerAlign(0);
break;
- case BuiltinType::OCLSampler: {
- auto AS = getTargetAddressSpace(LangAS::opencl_constant);
- Width = Target->getPointerWidth(AS);
- Align = Target->getPointerAlign(AS);
- break;
- }
+ case BuiltinType::OCLSampler:
case BuiltinType::OCLEvent:
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
case BuiltinType::OCLReserveID:
- // Currently these types are pointers to opaque types.
- Width = Target->getPointerWidth(0);
- Align = Target->getPointerAlign(0);
- break;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
- {
- auto AS = getTargetAddressSpace(Target->getOpenCLImageAddrSpace());
- Width = Target->getPointerWidth(AS);
- Align = Target->getPointerAlign(AS);
- }
+ AS = getTargetAddressSpace(
+ Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T)));
+ Width = Target->getPointerWidth(AS);
+ Align = Target->getPointerAlign(AS);
+ break;
}
break;
case Type::ObjCObjectPointer:
Width = Target->getPointerWidth(0);
Align = Target->getPointerAlign(0);
break;
- case Type::BlockPointer: {
- unsigned AS = getTargetAddressSpace(
- cast<BlockPointerType>(T)->getPointeeType());
+ case Type::BlockPointer:
+ AS = getTargetAddressSpace(cast<BlockPointerType>(T)->getPointeeType());
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
- }
case Type::LValueReference:
- case Type::RValueReference: {
+ case Type::RValueReference:
// alignof and sizeof should never enter this code path here, so we go
// the pointer route.
- unsigned AS = getTargetAddressSpace(
- cast<ReferenceType>(T)->getPointeeType());
+ AS = getTargetAddressSpace(cast<ReferenceType>(T)->getPointeeType());
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
- }
- case Type::Pointer: {
- unsigned AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType());
+ case Type::Pointer:
+ AS = getTargetAddressSpace(cast<PointerType>(T)->getPointeeType());
Width = Target->getPointerWidth(AS);
Align = Target->getPointerAlign(AS);
break;
- }
case Type::MemberPointer: {
const MemberPointerType *MPT = cast<MemberPointerType>(T);
- std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
+ CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);
+ Width = MPI.Width;
+ Align = MPI.Align;
break;
}
case Type::Complex: {
@@ -1938,11 +1966,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
break;
- case Type::Pipe: {
+ case Type::Pipe:
Width = Target->getPointerWidth(getTargetAddressSpace(LangAS::opencl_global));
Align = Target->getPointerAlign(getTargetAddressSpace(LangAS::opencl_global));
- }
-
+ break;
}
assert(llvm::isPowerOf2_32(Align) && "Alignment must be power of 2");
@@ -2055,7 +2082,6 @@ CharUnits ASTContext::getOffsetOfBaseWithVBPtr(const CXXRecordDecl *RD) const {
/// super class and then collects all ivars, including those synthesized for
/// current class. This routine is used for implementation of current class
/// when all ivars, declared and synthesized are known.
-///
void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
bool leafClass,
SmallVectorImpl<const ObjCIvarDecl*> &Ivars) const {
@@ -2107,6 +2133,171 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
}
}
+static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
+ const RecordDecl *RD) {
+ assert(RD->isUnion() && "Must be union type");
+ CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl());
+
+ for (const auto *Field : RD->fields()) {
+ if (!Context.hasUniqueObjectRepresentations(Field->getType()))
+ return false;
+ CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType());
+ if (FieldSize != UnionSize)
+ return false;
+ }
+ return true;
+}
+
+bool isStructEmpty(QualType Ty) {
+ const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
+
+ if (!RD->field_empty())
+ return false;
+
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD))
+ return ClassDecl->isEmpty();
+
+ return true;
+}
+
+static llvm::Optional<int64_t>
+structHasUniqueObjectRepresentations(const ASTContext &Context,
+ const RecordDecl *RD) {
+ assert(!RD->isUnion() && "Must be struct/class type");
+ const auto &Layout = Context.getASTRecordLayout(RD);
+
+ int64_t CurOffsetInBits = 0;
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) {
+ if (ClassDecl->isDynamicClass())
+ return llvm::None;
+
+ SmallVector<std::pair<QualType, int64_t>, 4> Bases;
+ for (const auto Base : ClassDecl->bases()) {
+ // Empty types can be inherited from, and non-empty types can potentially
+ // have tail padding, so just make sure there isn't an error.
+ if (!isStructEmpty(Base.getType())) {
+ llvm::Optional<int64_t> Size = structHasUniqueObjectRepresentations(
+ Context, Base.getType()->getAs<RecordType>()->getDecl());
+ if (!Size)
+ return llvm::None;
+ Bases.emplace_back(Base.getType(), Size.getValue());
+ }
+ }
+
+ std::sort(
+ Bases.begin(), Bases.end(), [&](const std::pair<QualType, int64_t> &L,
+ const std::pair<QualType, int64_t> &R) {
+ return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) <
+ Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
+ });
+
+ for (const auto Base : Bases) {
+ int64_t BaseOffset = Context.toBits(
+ Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
+ int64_t BaseSize = Base.second;
+ if (BaseOffset != CurOffsetInBits)
+ return llvm::None;
+ CurOffsetInBits = BaseOffset + BaseSize;
+ }
+ }
+
+ for (const auto *Field : RD->fields()) {
+ if (!Field->getType()->isReferenceType() &&
+ !Context.hasUniqueObjectRepresentations(Field->getType()))
+ return llvm::None;
+
+ int64_t FieldSizeInBits =
+ Context.toBits(Context.getTypeSizeInChars(Field->getType()));
+ if (Field->isBitField()) {
+ int64_t BitfieldSize = Field->getBitWidthValue(Context);
+
+ if (BitfieldSize > FieldSizeInBits)
+ return llvm::None;
+ FieldSizeInBits = BitfieldSize;
+ }
+
+ int64_t FieldOffsetInBits = Context.getFieldOffset(Field);
+
+ if (FieldOffsetInBits != CurOffsetInBits)
+ return llvm::None;
+
+ CurOffsetInBits = FieldSizeInBits + FieldOffsetInBits;
+ }
+
+ return CurOffsetInBits;
+}
+
+bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
+ // C++17 [meta.unary.prop]:
+ // The predicate condition for a template specialization
+ // has_unique_object_representations<T> shall be
+ // satisfied if and only if:
+ // (9.1) - T is trivially copyable, and
+ // (9.2) - any two objects of type T with the same value have the same
+ // object representation, where two objects
+ // of array or non-union class type are considered to have the same value
+ // if their respective sequences of
+ // direct subobjects have the same values, and two objects of union type
+ // are considered to have the same
+ // value if they have the same active member and the corresponding members
+ // have the same value.
+ // The set of scalar types for which this condition holds is
+ // implementation-defined. [ Note: If a type has padding
+ // bits, the condition does not hold; otherwise, the condition holds true
+ // for unsigned integral types. -- end note ]
+ assert(!Ty.isNull() && "Null QualType sent to unique object rep check");
+
+ // Arrays are unique only if their element type is unique.
+ if (Ty->isArrayType())
+ return hasUniqueObjectRepresentations(getBaseElementType(Ty));
+
+ // (9.1) - T is trivially copyable...
+ if (!Ty.isTriviallyCopyableType(*this))
+ return false;
+
+ // All integrals and enums are unique.
+ if (Ty->isIntegralOrEnumerationType())
+ return true;
+
+ // All other pointers are unique.
+ if (Ty->isPointerType())
+ return true;
+
+ if (Ty->isMemberPointerType()) {
+ const MemberPointerType *MPT = Ty->getAs<MemberPointerType>();
+ return !ABI->getMemberPointerInfo(MPT).HasPadding;
+ }
+
+ if (Ty->isRecordType()) {
+ const RecordDecl *Record = Ty->getAs<RecordType>()->getDecl();
+
+ if (Record->isInvalidDecl())
+ return false;
+
+ if (Record->isUnion())
+ return unionHasUniqueObjectRepresentations(*this, Record);
+
+ Optional<int64_t> StructSize =
+ structHasUniqueObjectRepresentations(*this, Record);
+
+ return StructSize &&
+ StructSize.getValue() == static_cast<int64_t>(getTypeSize(Ty));
+ }
+
+ // FIXME: More cases to handle here (list by rsmith):
+ // vectors (careful about, eg, vector of 3 foo)
+ // _Complex int and friends
+ // _Atomic T
+ // Obj-C block pointers
+ // Obj-C object pointers
+ // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t,
+ // clk_event_t, queue_t, reserve_id_t)
+ // There're also Obj-C class types and the Obj-C selector type, but I think it
+ // makes sense for those to return false here.
+
+ return false;
+}
+
unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
unsigned count = 0;
// Count ivars declared in class extension.
@@ -2139,7 +2330,8 @@ bool ASTContext::isSentinelNullExpr(const Expr *E) {
return false;
}
-/// \brief Get the implementation of ObjCInterfaceDecl,or NULL if none exists.
+/// \brief Get the implementation of ObjCInterfaceDecl, or nullptr if none
+/// exists.
ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
I = ObjCImpls.find(D);
@@ -2147,7 +2339,9 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)
return cast<ObjCImplementationDecl>(I->second);
return nullptr;
}
-/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
+
+/// \brief Get the implementation of ObjCCategoryDecl, or nullptr if none
+/// exists.
ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
I = ObjCImpls.find(D);
@@ -2162,6 +2356,7 @@ void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
assert(IFaceD && ImplD && "Passed null params");
ObjCImpls[IFaceD] = ImplD;
}
+
/// \brief Set the implementation of ObjCCategoryDecl.
void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD) {
@@ -2195,7 +2390,7 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
return nullptr;
}
-/// \brief Get the copy initialization expression of VarDecl,or NULL if
+/// \brief Get the copy initialization expression of VarDecl, or nullptr if
/// none exists.
Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
assert(VD && "Passed null params");
@@ -2280,8 +2475,8 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
return QualType(eq, fastQuals);
}
-QualType
-ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const {
+QualType ASTContext::getAddrSpaceQualType(QualType T,
+ LangAS AddressSpace) const {
QualType CanT = getCanonicalType(T);
if (CanT.getAddressSpace() == AddressSpace)
return T;
@@ -2300,6 +2495,27 @@ ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) const {
return getExtQualType(TypeNode, Quals);
}
+QualType ASTContext::removeAddrSpaceQualType(QualType T) const {
+ // If we are composing extended qualifiers together, merge together
+ // into one ExtQuals node.
+ QualifierCollector Quals;
+ const Type *TypeNode = Quals.strip(T);
+
+ // If the qualifier doesn't have an address space just return it.
+ if (!Quals.hasAddressSpace())
+ return T;
+
+ Quals.removeAddressSpace();
+
+ // Removal of the address space can mean there are no longer any
+ // non-fast qualifiers, so creating an ExtQualType isn't possible (asserts)
+ // or required.
+ if (Quals.hasNonFastQualifiers())
+ return getExtQualType(TypeNode, Quals);
+ else
+ return QualType(TypeNode, Quals.getFastQualifiers());
+}
+
QualType ASTContext::getObjCGCQualType(QualType T,
Qualifiers::GC GCAttr) const {
QualType CanT = getCanonicalType(T);
@@ -2393,7 +2609,7 @@ static QualType getFunctionTypeWithExceptionSpec(
bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
QualType U) {
return hasSameType(T, U) ||
- (getLangOpts().CPlusPlus1z &&
+ (getLangOpts().CPlusPlus17 &&
hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
}
@@ -2750,6 +2966,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Vector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
+ case Type::DependentAddressSpace:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
@@ -3098,6 +3315,41 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
return QualType(New, 0);
}
+QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
+ Expr *AddrSpaceExpr,
+ SourceLocation AttrLoc) const {
+ assert(AddrSpaceExpr->isInstantiationDependent());
+
+ QualType canonPointeeType = getCanonicalType(PointeeType);
+
+ void *insertPos = nullptr;
+ llvm::FoldingSetNodeID ID;
+ DependentAddressSpaceType::Profile(ID, *this, canonPointeeType,
+ AddrSpaceExpr);
+
+ DependentAddressSpaceType *canonTy =
+ DependentAddressSpaceTypes.FindNodeOrInsertPos(ID, insertPos);
+
+ if (!canonTy) {
+ canonTy = new (*this, TypeAlignment)
+ DependentAddressSpaceType(*this, canonPointeeType,
+ QualType(), AddrSpaceExpr, AttrLoc);
+ DependentAddressSpaceTypes.InsertNode(canonTy, insertPos);
+ Types.push_back(canonTy);
+ }
+
+ if (canonPointeeType == PointeeType &&
+ canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
+ return QualType(canonTy, 0);
+
+ DependentAddressSpaceType *sugaredType
+ = new (*this, TypeAlignment)
+ DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
+ AddrSpaceExpr, AttrLoc);
+ Types.push_back(sugaredType);
+ return QualType(sugaredType, 0);
+}
+
/// \brief Determine whether \p T is canonical as the result type of a function.
static bool isCanonicalResultType(QualType T) {
return T.isCanonical() &&
@@ -3106,7 +3358,6 @@ static bool isCanonicalResultType(QualType T) {
}
/// getFunctionNoProtoType - Return a K&R style C function type like 'int()'.
-///
QualType
ASTContext::getFunctionNoProtoType(QualType ResultTy,
const FunctionType::ExtInfo &Info) const {
@@ -3222,7 +3473,7 @@ QualType ASTContext::getFunctionTypeInternal(
Unique = true;
}
- bool NoexceptInType = getLangOpts().CPlusPlus1z;
+ bool NoexceptInType = getLangOpts().CPlusPlus17;
bool IsCanonicalExceptionSpec =
isCanonicalExceptionSpecification(EPI.ExceptionSpec, NoexceptInType);
@@ -3358,7 +3609,7 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {
llvm::FoldingSetNodeID ID;
PipeType::Profile(ID, T, ReadOnly);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (PipeType *PT = PipeTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -3986,7 +4237,7 @@ SortAndUniqueProtocols(SmallVectorImpl<ObjCProtocolDecl *> &Protocols) {
QualType ASTContext::getObjCObjectType(QualType BaseType,
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) const {
- return getObjCObjectType(BaseType, { },
+ return getObjCObjectType(BaseType, {},
llvm::makeArrayRef(Protocols, NumProtocols),
/*isKindOf=*/false);
}
@@ -4123,13 +4374,13 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// FIXME: Check for protocols to which the class type is already
// known to conform.
- return getObjCObjectType(type, { }, protocols, false);
+ return getObjCObjectType(type, {}, protocols, false);
}
// id<protocol-list>
if (type->isObjCIdType()) {
const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
- type = getObjCObjectType(ObjCBuiltinIdTy, { }, protocols,
+ type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
}
@@ -4137,7 +4388,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// Class<protocol-list>
if (type->isObjCClassType()) {
const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
- type = getObjCObjectType(ObjCBuiltinClassTy, { }, protocols,
+ type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
}
@@ -4512,7 +4763,7 @@ QualType ASTContext::getAutoRRefDeductType() const {
/// getTagDeclType - Return the unique reference to the type for the
/// specified TagDecl (struct/union/class/enum) decl.
QualType ASTContext::getTagDeclType(const TagDecl *Decl) const {
- assert (Decl);
+ assert(Decl);
// FIXME: What is the design on getTagDeclType when it requires casting
// away const? mutable?
return getTypeDeclType(const_cast<TagDecl*>(Decl));
@@ -4569,6 +4820,13 @@ QualType ASTContext::getPointerDiffType() const {
return getFromTargetType(Target->getPtrDiffType(0));
}
+/// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+/// integer type. The standard (C11 7.21.6.1p7) refers to this type
+/// in the definition of %tu format specifier.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+ return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
/// \brief Return the unique type for "pid_t" defined in
/// <sys/types.h>. We need this to compute the correct type for vfork().
QualType ASTContext::getProcessIDType() const {
@@ -5051,6 +5309,7 @@ static FloatingRank getFloatingRank(QualType T) {
assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
switch (T->getAs<BuiltinType>()->getKind()) {
default: llvm_unreachable("getFloatingRank(): not a floating type");
+ case BuiltinType::Float16: return Float16Rank;
case BuiltinType::Half: return HalfRank;
case BuiltinType::Float: return FloatRank;
case BuiltinType::Double: return DoubleRank;
@@ -5068,6 +5327,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
FloatingRank EltRank = getFloatingRank(Size);
if (Domain->isComplexType()) {
switch (EltRank) {
+ case Float16Rank:
case HalfRank: llvm_unreachable("Complex half is not supported");
case FloatRank: return FloatComplexTy;
case DoubleRank: return DoubleComplexTy;
@@ -5078,6 +5338,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
assert(Domain->isRealFloatingType() && "Unknown domain!");
switch (EltRank) {
+ case Float16Rank: return HalfTy;
case HalfRank: return HalfTy;
case FloatRank: return FloatTy;
case DoubleRank: return DoubleTy;
@@ -5455,6 +5716,46 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
return getTagDeclType(BlockDescriptorExtendedType);
}
+TargetInfo::OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const {
+ auto BT = dyn_cast<BuiltinType>(T);
+
+ if (!BT) {
+ if (isa<PipeType>(T))
+ return TargetInfo::OCLTK_Pipe;
+
+ return TargetInfo::OCLTK_Default;
+ }
+
+ switch (BT->getKind()) {
+#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
+ case BuiltinType::Id: \
+ return TargetInfo::OCLTK_Image;
+#include "clang/Basic/OpenCLImageTypes.def"
+
+ case BuiltinType::OCLClkEvent:
+ return TargetInfo::OCLTK_ClkEvent;
+
+ case BuiltinType::OCLEvent:
+ return TargetInfo::OCLTK_Event;
+
+ case BuiltinType::OCLQueue:
+ return TargetInfo::OCLTK_Queue;
+
+ case BuiltinType::OCLReserveID:
+ return TargetInfo::OCLTK_ReserveID;
+
+ case BuiltinType::OCLSampler:
+ return TargetInfo::OCLTK_Sampler;
+
+ default:
+ return TargetInfo::OCLTK_Default;
+ }
+}
+
+LangAS ASTContext::getOpenCLTypeAddrSpace(const Type *T) const {
+ return Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T));
+}
+
/// BlockRequiresCopying - Returns true if byref variable "D" of type "Ty"
/// requires copy/dispose. Note that this must match the logic
/// in buildByrefHelpers.
@@ -5497,7 +5798,6 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
bool ASTContext::getByrefLifetime(QualType Ty,
Qualifiers::ObjCLifetime &LifeTime,
bool &HasByrefExtendedLayout) const {
-
if (!getLangOpts().ObjC1 ||
getLangOpts().getGC() != LangOptions::NonGC)
return false;
@@ -5565,14 +5865,14 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {
// In almost all cases, it's a weak definition.
auto *First = VD->getFirstDecl();
- if (!First->isConstexpr() || First->isInlineSpecified() ||
- !VD->isStaticDataMember())
+ if (First->isInlineSpecified() || !First->isStaticDataMember())
return InlineVariableDefinitionKind::Weak;
// If there's a file-context declaration in this translation unit, it's a
// non-discardable definition.
for (auto *D : VD->redecls())
- if (D->getLexicalDeclContext()->isFileContext())
+ if (D->getLexicalDeclContext()->isFileContext() &&
+ !D->isInlineSpecified() && (D->isConstexpr() || First->isConstexpr()))
return InlineVariableDefinitionKind::Strong;
// If we've not seen one yet, we don't know.
@@ -5602,7 +5902,6 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
- SourceLocation Loc;
CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
CharUnits ParmOffset = PtrSize;
for (auto PI : Decl->parameters()) {
@@ -5610,7 +5909,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
- assert (sz.isPositive() && "BlockExpr - Incomplete param type");
+ assert(sz.isPositive() && "BlockExpr - Incomplete param type");
ParmOffset += sz;
}
// Size of the argument frame
@@ -5710,7 +6009,6 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
- SourceLocation Loc;
CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
// The first two arguments (self and _cmd) are pointers; account for
// their size.
@@ -5722,8 +6020,8 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
if (sz.isZero())
continue;
- assert (sz.isPositive() &&
- "getObjCEncodingForMethodDecl - Incomplete param type");
+ assert(sz.isPositive() &&
+ "getObjCEncodingForMethodDecl - Incomplete param type");
ParmOffset += sz;
}
S += charUnitsToString(ParmOffset);
@@ -5870,7 +6168,6 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
/// Another legacy compatibility encoding: 32-bit longs are encoded as
/// 'l' or 'L' , but not always. For typedefs, we need to use
/// 'i' or 'I' instead if encoding a struct field, or a pointer!
-///
void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {
if (isa<TypedefType>(PointeeTy.getTypePtr())) {
if (const BuiltinType *BT = PointeeTy->getAs<BuiltinType>()) {
@@ -5935,6 +6232,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*
+ case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half:
// FIXME: potentially need @encodes for these!
@@ -6176,9 +6474,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
= dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
llvm::raw_string_ostream OS(S);
- TemplateSpecializationType::PrintTemplateArgumentList(OS,
- TemplateArgs.asArray(),
- (*this).getPrintingPolicy());
+ printTemplateArgumentList(OS, TemplateArgs.asArray(),
+ getPrintingPolicy());
}
} else {
S += '?';
@@ -6370,10 +6667,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Vector:
case Type::ExtVector:
// Until we have a coherent encoding of these three types, issue warning.
- { if (NotEncodedT)
- *NotEncodedT = T;
- return;
- }
+ if (NotEncodedT)
+ *NotEncodedT = T;
+ return;
// We could see an undeduced auto type here during error recovery.
// Just ignore it.
@@ -6557,7 +6853,7 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
TypedefDecl *ASTContext::getObjCIdDecl() const {
if (!ObjCIdDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinIdTy, { }, { });
+ QualType T = getObjCObjectType(ObjCBuiltinIdTy, {}, {});
T = getObjCObjectPointerType(T);
ObjCIdDecl = buildImplicitTypedef(T, "id");
}
@@ -6574,7 +6870,7 @@ TypedefDecl *ASTContext::getObjCSelDecl() const {
TypedefDecl *ASTContext::getObjCClassDecl() const {
if (!ObjCClassDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinClassTy, { }, { });
+ QualType T = getObjCObjectType(ObjCBuiltinClassTy, {}, {});
T = getObjCObjectPointerType(T);
ObjCClassDecl = buildImplicitTypedef(T, "Class");
}
@@ -7236,7 +7532,7 @@ bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
QualType rhs) {
const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();
const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
- assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
+ assert((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
@@ -7374,7 +7670,6 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
/// canAssignObjCInterfaces - Return true if the two interface types are
/// compatible for assignment from RHS to LHS. This handles validation of any
/// protocol qualifiers on the LHS or RHS.
-///
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectPointerType *LHSOPT,
const ObjCObjectPointerType *RHSOPT) {
const ObjCObjectType* LHS = LHSOPT->getObjectType();
@@ -7480,7 +7775,6 @@ bool ASTContext::canAssignObjCInterfacesInBlockPointer(
static int compareObjCProtocolsByName(ObjCProtocolDecl * const *lhs,
ObjCProtocolDecl * const *rhs) {
return (*lhs)->getName().compare((*rhs)->getName());
-
}
/// getIntersectionOfProtocols - This routine finds the intersection of set
@@ -7649,7 +7943,7 @@ QualType ASTContext::areCommonBaseCompatible(
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
- LHSTypeArgs = { };
+ LHSTypeArgs = {};
anyChanges = true;
}
@@ -7700,7 +7994,7 @@ QualType ASTContext::areCommonBaseCompatible(
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
- RHSTypeArgs = { };
+ RHSTypeArgs = {};
anyChanges = true;
}
@@ -7962,9 +8256,17 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lproto->getTypeQuals() != rproto->getTypeQuals())
return QualType();
- if (!doFunctionTypesMatchOnExtParameterInfos(rproto, lproto))
+ SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;
+ bool canUseLeft, canUseRight;
+ if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight,
+ newParamInfos))
return QualType();
+ if (!canUseLeft)
+ allLTypes = false;
+ if (!canUseRight)
+ allRTypes = false;
+
// Check parameter type compatibility
SmallVector<QualType, 10> types;
for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) {
@@ -7995,6 +8297,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo();
EPI.ExtInfo = einfo;
+ EPI.ExtParameterInfos =
+ newParamInfos.empty() ? nullptr : newParamInfos.data();
return getFunctionType(retType, types, EPI);
}
@@ -8328,7 +8632,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return QualType();
}
- case Type::ObjCObjectPointer: {
+ case Type::ObjCObjectPointer:
if (OfBlockPointer) {
if (canAssignObjCInterfacesInBlockPointer(
LHS->getAs<ObjCObjectPointerType>(),
@@ -8342,38 +8646,59 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return LHS;
return QualType();
- }
case Type::Pipe:
- {
assert(LHS != RHS &&
"Equivalent pipe types should have already been handled!");
return QualType();
}
- }
llvm_unreachable("Invalid Type::Class!");
}
-bool ASTContext::doFunctionTypesMatchOnExtParameterInfos(
- const FunctionProtoType *firstFnType,
- const FunctionProtoType *secondFnType) {
+bool ASTContext::mergeExtParameterInfo(
+ const FunctionProtoType *FirstFnType, const FunctionProtoType *SecondFnType,
+ bool &CanUseFirst, bool &CanUseSecond,
+ SmallVectorImpl<FunctionProtoType::ExtParameterInfo> &NewParamInfos) {
+ assert(NewParamInfos.empty() && "param info list not empty");
+ CanUseFirst = CanUseSecond = true;
+ bool FirstHasInfo = FirstFnType->hasExtParameterInfos();
+ bool SecondHasInfo = SecondFnType->hasExtParameterInfos();
+
// Fast path: if the first type doesn't have ext parameter infos,
- // we match if and only if they second type also doesn't have them.
- if (!firstFnType->hasExtParameterInfos())
- return !secondFnType->hasExtParameterInfos();
+ // we match if and only if the second type also doesn't have them.
+ if (!FirstHasInfo && !SecondHasInfo)
+ return true;
- // Otherwise, we can only match if the second type has them.
- if (!secondFnType->hasExtParameterInfos())
- return false;
+ bool NeedParamInfo = false;
+ size_t E = FirstHasInfo ? FirstFnType->getExtParameterInfos().size()
+ : SecondFnType->getExtParameterInfos().size();
- auto firstEPI = firstFnType->getExtParameterInfos();
- auto secondEPI = secondFnType->getExtParameterInfos();
- assert(firstEPI.size() == secondEPI.size());
+ for (size_t I = 0; I < E; ++I) {
+ FunctionProtoType::ExtParameterInfo FirstParam, SecondParam;
+ if (FirstHasInfo)
+ FirstParam = FirstFnType->getExtParameterInfo(I);
+ if (SecondHasInfo)
+ SecondParam = SecondFnType->getExtParameterInfo(I);
- for (size_t i = 0, n = firstEPI.size(); i != n; ++i) {
- if (firstEPI[i] != secondEPI[i])
+ // Cannot merge unless everything except the noescape flag matches.
+ if (FirstParam.withIsNoEscape(false) != SecondParam.withIsNoEscape(false))
return false;
+
+ bool FirstNoEscape = FirstParam.isNoEscape();
+ bool SecondNoEscape = SecondParam.isNoEscape();
+ bool IsNoEscape = FirstNoEscape && SecondNoEscape;
+ NewParamInfos.push_back(FirstParam.withIsNoEscape(IsNoEscape));
+ if (NewParamInfos.back().getOpaqueValue())
+ NeedParamInfo = true;
+ if (FirstNoEscape != IsNoEscape)
+ CanUseFirst = false;
+ if (SecondNoEscape != IsNoEscape)
+ CanUseSecond = false;
}
+
+ if (!NeedParamInfo)
+ NewParamInfos.clear();
+
return true;
}
@@ -8502,7 +8827,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
}
}
-ASTMutationListener::~ASTMutationListener() { }
+ASTMutationListener::~ASTMutationListener() = default;
void ASTMutationListener::DeducedReturnType(const FunctionDecl *FD,
QualType ReturnType) {}
@@ -8554,7 +8879,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
assert(HowLong <= 2 && "Can't have LLLL modifier");
++HowLong;
break;
- case 'N': {
+ case 'N':
// 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise.
assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!");
@@ -8564,7 +8889,6 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
if (Context.getTargetInfo().getLongWidth() == 32)
++HowLong;
break;
- }
case 'W':
// This modifier represents int64 type.
assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
@@ -8719,10 +9043,9 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Type = Context.getComplexType(ElementType);
break;
}
- case 'Y' : {
+ case 'Y':
Type = Context.getPointerDiffType();
break;
- }
case 'P':
Type = Context.getFILEType();
if (Type.isNull()) {
@@ -8767,8 +9090,8 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
char *End;
unsigned AddrSpace = strtoul(Str, &End, 10);
if (End != Str && AddrSpace != 0) {
- Type = Context.getAddrSpaceQualType(
- Type, AddrSpace + LangAS::FirstTargetAddressSpace);
+ Type = Context.getAddrSpaceQualType(Type,
+ getLangASFromTargetAS(AddrSpace));
Str = End;
}
if (c == '*')
@@ -8860,6 +9183,12 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
if (!FD->isExternallyVisible())
return GVA_Internal;
+ // Non-user-provided functions get emitted as weak definitions with every
+ // use, no matter whether they've been explicitly instantiated etc.
+ if (auto *MD = dyn_cast<CXXMethodDecl>(FD))
+ if (!MD->isUserProvided())
+ return GVA_DiscardableODR;
+
GVALinkage External;
switch (FD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
@@ -8912,7 +9241,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
}
static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
- GVALinkage L, const Decl *D) {
+ const Decl *D, GVALinkage L) {
// See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
// dllexport/dllimport on inline functions.
if (D->hasAttr<DLLImportAttr>()) {
@@ -8931,25 +9260,37 @@ static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
return L;
}
-GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
- auto L = adjustGVALinkageForAttributes(
- *this, basicGVALinkageForFunction(*this, FD), FD);
- auto EK = ExternalASTSource::EK_ReplyHazy;
- if (auto *Ext = getExternalSource())
- EK = Ext->hasExternalDefinitions(FD);
- switch (EK) {
+/// Adjust the GVALinkage for a declaration based on what an external AST source
+/// knows about whether there can be other definitions of this declaration.
+static GVALinkage
+adjustGVALinkageForExternalDefinitionKind(const ASTContext &Ctx, const Decl *D,
+ GVALinkage L) {
+ ExternalASTSource *Source = Ctx.getExternalSource();
+ if (!Source)
+ return L;
+
+ switch (Source->hasExternalDefinitions(D)) {
case ExternalASTSource::EK_Never:
+ // Other translation units rely on us to provide the definition.
if (L == GVA_DiscardableODR)
return GVA_StrongODR;
break;
+
case ExternalASTSource::EK_Always:
return GVA_AvailableExternally;
+
case ExternalASTSource::EK_ReplyHazy:
break;
}
return L;
}
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
+ return adjustGVALinkageForExternalDefinitionKind(*this, FD,
+ adjustGVALinkageForAttributes(*this, FD,
+ basicGVALinkageForFunction(*this, FD)));
+}
+
static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
const VarDecl *VD) {
if (!VD->isExternallyVisible())
@@ -9028,8 +9369,9 @@ static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
}
GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
- return adjustGVALinkageForAttributes(
- *this, basicGVALinkageForVariable(*this, VD), VD);
+ return adjustGVALinkageForExternalDefinitionKind(*this, VD,
+ adjustGVALinkageForAttributes(*this, VD,
+ basicGVALinkageForVariable(*this, VD)));
}
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
@@ -9112,9 +9454,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return false;
// Variables that can be needed in other TUs are required.
- if (!isDiscardableGVALinkage(GetGVALinkageForVariable(VD)))
+ auto Linkage = GetGVALinkageForVariable(VD);
+ if (!isDiscardableGVALinkage(Linkage))
return true;
+ // We never need to emit a variable that is available in another TU.
+ if (Linkage == GVA_AvailableExternally)
+ return false;
+
// Variables that have destruction with side-effects are required.
if (VD->getType().isDestructedType())
return true;
@@ -9148,7 +9495,7 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
case LangOptions::DCC_CDecl:
return CC_C;
case LangOptions::DCC_FastCall:
- if (getTargetInfo().hasFeature("sse2"))
+ if (getTargetInfo().hasFeature("sse2") && !IsVariadic)
return CC_X86FastCall;
break;
case LangOptions::DCC_StdCall:
@@ -9160,6 +9507,11 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
if (!IsVariadic)
return CC_X86VectorCall;
break;
+ case LangOptions::DCC_RegCall:
+ // __regcall cannot be applied to variadic functions.
+ if (!IsVariadic)
+ return CC_X86RegCall;
+ break;
}
return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown);
}
@@ -9196,7 +9548,7 @@ MangleContext *ASTContext::createMangleContext() {
llvm_unreachable("Unsupported ABI");
}
-CXXABI::~CXXABI() {}
+CXXABI::~CXXABI() = default;
size_t ASTContext::getSideTableAllocatedMemory() const {
return ASTRecordLayouts.getMemorySize() +
@@ -9359,9 +9711,7 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits);
}
-namespace {
-
-ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(
+static ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(
ASTContext::ParentMapPointers::mapped_type U) {
if (const auto *D = U.dyn_cast<const Decl *>())
return ast_type_traits::DynTypedNode::create(*D);
@@ -9370,6 +9720,8 @@ ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(
return *U.get<ast_type_traits::DynTypedNode *>();
}
+namespace {
+
/// Template specializations to abstract away from pointers and TypeLocs.
/// @{
template <typename T>
@@ -9410,7 +9762,9 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
}
private:
- typedef RecursiveASTVisitor<ParentMapASTVisitor> VisitorBase;
+ friend class RecursiveASTVisitor<ParentMapASTVisitor>;
+
+ using VisitorBase = RecursiveASTVisitor<ParentMapASTVisitor>;
ParentMapASTVisitor(ASTContext::ParentMapPointers *Parents,
ASTContext::ParentMapOtherNodes *OtherParents)
@@ -9419,6 +9773,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
bool shouldVisitTemplateInstantiations() const {
return true;
}
+
bool shouldVisitImplicitCode() const {
return true;
}
@@ -9508,11 +9863,9 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
ASTContext::ParentMapPointers *Parents;
ASTContext::ParentMapOtherNodes *OtherParents;
llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
-
- friend class RecursiveASTVisitor<ParentMapASTVisitor>;
};
-} // anonymous namespace
+} // namespace
template <typename NodeTy, typename MapTy>
static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
@@ -9568,25 +9921,25 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
if (!hasSameType(DeclVar->getType(), ImplVar->getType()))
return false;
}
+
return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
-
}
uint64_t ASTContext::getTargetNullPointerValue(QualType QT) const {
- unsigned AS;
+ LangAS AS;
if (QT->getUnqualifiedDesugaredType()->isNullPtrType())
- AS = 0;
+ AS = LangAS::Default;
else
AS = QT->getPointeeType().getAddressSpace();
return getTargetInfo().getNullPointerValue(AS);
}
-unsigned ASTContext::getTargetAddressSpace(unsigned AS) const {
- if (AS >= LangAS::FirstTargetAddressSpace)
- return AS - LangAS::FirstTargetAddressSpace;
+unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {
+ if (isTargetAddressSpace(AS))
+ return toTargetAddressSpace(AS);
else
- return (*AddrSpaceMap)[AS];
+ return (*AddrSpaceMap)[(unsigned)AS];
}
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 92ed7da94d8e..157b29fd84b6 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -537,6 +537,7 @@ namespace {
void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
void VisitCXXThisExpr(const CXXThisExpr *Node);
void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
+ void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
void VisitCXXConstructExpr(const CXXConstructExpr *Node);
void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
void VisitCXXNewExpr(const CXXNewExpr *Node);
@@ -1184,7 +1185,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
I != E; ++I)
dumpCXXCtorInitializer(*I);
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D))
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
if (MD->size_overridden_methods() != 0) {
auto dumpOverride =
[=](const CXXMethodDecl *D) {
@@ -1194,16 +1195,18 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
};
dumpChild([=] {
- auto FirstOverrideItr = MD->begin_overridden_methods();
+ auto Overrides = MD->overridden_methods();
OS << "Overrides: [ ";
- dumpOverride(*FirstOverrideItr);
+ dumpOverride(*Overrides.begin());
for (const auto *Override :
- llvm::make_range(FirstOverrideItr + 1,
- MD->end_overridden_methods()))
+ llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
+ OS << ", ";
dumpOverride(Override);
+ }
OS << " ]";
});
}
+ }
if (D->doesThisDeclarationHaveABody())
dumpStmt(D->getBody());
@@ -1313,6 +1316,16 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
dumpStmt(D->getCombiner());
if (auto *Initializer = D->getInitializer()) {
OS << " initializer";
+ switch (D->getInitializerKind()) {
+ case OMPDeclareReductionDecl::DirectInit:
+ OS << " omp_priv = ";
+ break;
+ case OMPDeclareReductionDecl::CopyInit:
+ OS << " omp_priv ()";
+ break;
+ case OMPDeclareReductionDecl::CallInit:
+ break;
+ }
dumpStmt(Initializer);
}
}
@@ -1362,6 +1375,128 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
if (!D->isCompleteDefinition())
return;
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "DefinitionData";
+ }
+#define FLAG(fn, name) if (D->fn()) OS << " " #name;
+ FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
+
+ FLAG(isGenericLambda, generic);
+ FLAG(isLambda, lambda);
+
+ FLAG(canPassInRegisters, pass_in_registers);
+ FLAG(isEmpty, empty);
+ FLAG(isAggregate, aggregate);
+ FLAG(isStandardLayout, standard_layout);
+ FLAG(isTriviallyCopyable, trivially_copyable);
+ FLAG(isPOD, pod);
+ FLAG(isTrivial, trivial);
+ FLAG(isPolymorphic, polymorphic);
+ FLAG(isAbstract, abstract);
+ FLAG(isLiteral, literal);
+
+ FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
+ FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
+ FLAG(hasMutableFields, has_mutable_fields);
+ FLAG(hasVariantMembers, has_variant_members);
+ FLAG(allowConstDefaultInit, can_const_default_init);
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "DefaultConstructor";
+ }
+ FLAG(hasDefaultConstructor, exists);
+ FLAG(hasTrivialDefaultConstructor, trivial);
+ FLAG(hasNonTrivialDefaultConstructor, non_trivial);
+ FLAG(hasUserProvidedDefaultConstructor, user_provided);
+ FLAG(hasConstexprDefaultConstructor, constexpr);
+ FLAG(needsImplicitDefaultConstructor, needs_implicit);
+ FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
+ });
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "CopyConstructor";
+ }
+ FLAG(hasSimpleCopyConstructor, simple);
+ FLAG(hasTrivialCopyConstructor, trivial);
+ FLAG(hasNonTrivialCopyConstructor, non_trivial);
+ FLAG(hasUserDeclaredCopyConstructor, user_declared);
+ FLAG(hasCopyConstructorWithConstParam, has_const_param);
+ FLAG(needsImplicitCopyConstructor, needs_implicit);
+ FLAG(needsOverloadResolutionForCopyConstructor,
+ needs_overload_resolution);
+ if (!D->needsOverloadResolutionForCopyConstructor())
+ FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
+ FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
+ });
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "MoveConstructor";
+ }
+ FLAG(hasMoveConstructor, exists);
+ FLAG(hasSimpleMoveConstructor, simple);
+ FLAG(hasTrivialMoveConstructor, trivial);
+ FLAG(hasNonTrivialMoveConstructor, non_trivial);
+ FLAG(hasUserDeclaredMoveConstructor, user_declared);
+ FLAG(needsImplicitMoveConstructor, needs_implicit);
+ FLAG(needsOverloadResolutionForMoveConstructor,
+ needs_overload_resolution);
+ if (!D->needsOverloadResolutionForMoveConstructor())
+ FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
+ });
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "CopyAssignment";
+ }
+ FLAG(hasTrivialCopyAssignment, trivial);
+ FLAG(hasNonTrivialCopyAssignment, non_trivial);
+ FLAG(hasCopyAssignmentWithConstParam, has_const_param);
+ FLAG(hasUserDeclaredCopyAssignment, user_declared);
+ FLAG(needsImplicitCopyAssignment, needs_implicit);
+ FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
+ FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
+ });
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "MoveAssignment";
+ }
+ FLAG(hasMoveAssignment, exists);
+ FLAG(hasSimpleMoveAssignment, simple);
+ FLAG(hasTrivialMoveAssignment, trivial);
+ FLAG(hasNonTrivialMoveAssignment, non_trivial);
+ FLAG(hasUserDeclaredMoveAssignment, user_declared);
+ FLAG(needsImplicitMoveAssignment, needs_implicit);
+ FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
+ });
+
+ dumpChild([=] {
+ {
+ ColorScope Color(*this, DeclKindNameColor);
+ OS << "Destructor";
+ }
+ FLAG(hasSimpleDestructor, simple);
+ FLAG(hasIrrelevantDestructor, irrelevant);
+ FLAG(hasTrivialDestructor, trivial);
+ FLAG(hasNonTrivialDestructor, non_trivial);
+ FLAG(hasUserDeclaredDestructor, user_declared);
+ FLAG(needsImplicitDestructor, needs_implicit);
+ FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
+ if (!D->needsOverloadResolutionForDestructor())
+ FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
+ });
+ });
+
for (const auto &I : D->bases()) {
dumpChild([=] {
if (I.isVirtual())
@@ -2166,12 +2301,24 @@ void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
<< " <" << Node->getCastKindName() << ">";
}
+void ASTDumper::VisitCXXUnresolvedConstructExpr(
+ const CXXUnresolvedConstructExpr *Node) {
+ VisitExpr(Node);
+ dumpType(Node->getTypeAsWritten());
+ if (Node->isListInitialization())
+ OS << " list";
+}
+
void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
VisitExpr(Node);
CXXConstructorDecl *Ctor = Node->getConstructor();
dumpType(Ctor->getType());
if (Node->isElidable())
OS << " elidable";
+ if (Node->isListInitialization())
+ OS << " list";
+ if (Node->isStdInitListInitialization())
+ OS << " std::initializer_list";
if (Node->requiresZeroInitialization())
OS << " zeroing";
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 2c0bb11cc4bc..84b0d7ecff93 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -58,7 +58,7 @@ namespace clang {
QualType VisitExtVectorType(const ExtVectorType *T);
QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
QualType VisitFunctionProtoType(const FunctionProtoType *T);
- // FIXME: UnresolvedUsingType
+ QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
QualType VisitParenType(const ParenType *T);
QualType VisitTypedefType(const TypedefType *T);
QualType VisitTypeOfExprType(const TypeOfExprType *T);
@@ -77,6 +77,7 @@ namespace clang {
QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
QualType VisitElaboratedType(const ElaboratedType *T);
// FIXME: DependentNameType
+ QualType VisitPackExpansionType(const PackExpansionType *T);
// FIXME: DependentTemplateSpecializationType
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
QualType VisitObjCObjectType(const ObjCObjectType *T);
@@ -128,27 +129,35 @@ namespace clang {
TemplateParameterList *ImportTemplateParameterList(
TemplateParameterList *Params);
TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
- TemplateArgumentLoc ImportTemplateArgumentLoc(
- const TemplateArgumentLoc &TALoc, bool &Error);
+ Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc(
+ const TemplateArgumentLoc &TALoc);
bool ImportTemplateArguments(const TemplateArgument *FromArgs,
unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs);
+ template <typename InContainerTy>
+ bool ImportTemplateArgumentListInfo(const InContainerTy &Container,
+ TemplateArgumentListInfo &ToTAInfo);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
bool Complain = true);
bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
+ bool IsStructuralMatch(FunctionTemplateDecl *From,
+ FunctionTemplateDecl *To);
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
Decl *VisitDecl(Decl *D);
+ Decl *VisitEmptyDecl(EmptyDecl *D);
Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
Decl *VisitNamespaceDecl(NamespaceDecl *D);
+ Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
Decl *VisitTypedefDecl(TypedefDecl *D);
Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
+ Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
Decl *VisitLabelDecl(LabelDecl *D);
Decl *VisitEnumDecl(EnumDecl *D);
Decl *VisitRecordDecl(RecordDecl *D);
@@ -170,6 +179,12 @@ namespace clang {
Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D);
+ Decl *VisitUsingDecl(UsingDecl *D);
+ Decl *VisitUsingShadowDecl(UsingShadowDecl *D);
+ Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+ Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+ Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+
ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list);
Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
@@ -185,6 +200,7 @@ namespace clang {
ClassTemplateSpecializationDecl *D);
Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
+ Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
// Importing statements
DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
@@ -265,13 +281,16 @@ namespace clang {
Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
+ Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+ Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
Expr *VisitExprWithCleanups(ExprWithCleanups *EWC);
Expr *VisitCXXThisExpr(CXXThisExpr *E);
Expr *VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+ Expr *VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
Expr *VisitMemberExpr(MemberExpr *E);
Expr *VisitCallExpr(CallExpr *E);
Expr *VisitInitListExpr(InitListExpr *E);
@@ -280,6 +299,7 @@ namespace clang {
Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
+ Expr *VisitTypeTraitExpr(TypeTraitExpr *E);
template<typename IIter, typename OIter>
@@ -566,6 +586,22 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
}
+QualType ASTNodeImporter::VisitUnresolvedUsingType(
+ const UnresolvedUsingType *T) {
+ UnresolvedUsingTypenameDecl *ToD = cast_or_null<UnresolvedUsingTypenameDecl>(
+ Importer.Import(T->getDecl()));
+ if (!ToD)
+ return QualType();
+
+ UnresolvedUsingTypenameDecl *ToPrevD =
+ cast_or_null<UnresolvedUsingTypenameDecl>(
+ Importer.Import(T->getDecl()->getPreviousDecl()));
+ if (!ToPrevD && T->getDecl()->getPreviousDecl())
+ return QualType();
+
+ return Importer.getToContext().getTypeDeclType(ToD, ToPrevD);
+}
+
QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
QualType ToInnerType = Importer.Import(T->getInnerType());
if (ToInnerType.isNull())
@@ -767,6 +803,15 @@ QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
ToQualifier, ToNamedType);
}
+QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
+ QualType Pattern = Importer.Import(T->getPattern());
+ if (Pattern.isNull())
+ return QualType();
+
+ return Importer.getToContext().getPackExpansionType(Pattern,
+ T->getNumExpansions());
+}
+
QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
ObjCInterfaceDecl *Class
= dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
@@ -1171,9 +1216,8 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
llvm_unreachable("Invalid template argument kind");
}
-TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc(
- const TemplateArgumentLoc &TALoc, bool &Error) {
- Error = false;
+Optional<TemplateArgumentLoc>
+ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) {
TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument());
TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
TemplateArgumentLocInfo ToInfo;
@@ -1181,12 +1225,12 @@ TemplateArgumentLoc ASTNodeImporter::ImportTemplateArgumentLoc(
Expr *E = Importer.Import(FromInfo.getAsExpr());
ToInfo = TemplateArgumentLocInfo(E);
if (!E)
- Error = true;
+ return None;
} else if (Arg.getKind() == TemplateArgument::Type) {
if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo()))
ToInfo = TemplateArgumentLocInfo(TSI);
else
- Error = true;
+ return None;
} else {
ToInfo = TemplateArgumentLocInfo(
Importer.Import(FromInfo.getTemplateQualifierLoc()),
@@ -1210,6 +1254,18 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
return false;
}
+template <typename InContainerTy>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+ const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
+ for (const auto &FromLoc : Container) {
+ if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc))
+ ToTAInfo.addArgument(*ToLoc);
+ else
+ return true;
+ }
+ return false;
+}
+
bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
RecordDecl *ToRecord, bool Complain) {
// Eliminate a potential failure point where we attempt to re-import
@@ -1243,6 +1299,14 @@ bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
}
+bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From,
+ FunctionTemplateDecl *To) {
+ StructuralEquivalenceContext Ctx(
+ Importer.getFromContext(), Importer.getToContext(),
+ Importer.getNonEquivalentDecls(), false, false);
+ return Ctx.IsStructurallyEquivalent(From, To);
+}
+
bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
EnumConstantDecl *ToEC)
{
@@ -1276,6 +1340,29 @@ Decl *ASTNodeImporter::VisitDecl(Decl *D) {
return nullptr;
}
+Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
+ // Import the context of this declaration.
+ DeclContext *DC = Importer.ImportContext(D->getDeclContext());
+ if (!DC)
+ return nullptr;
+
+ DeclContext *LexicalDC = DC;
+ if (D->getDeclContext() != D->getLexicalDeclContext()) {
+ LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+ if (!LexicalDC)
+ return nullptr;
+ }
+
+ // Import the location of this declaration.
+ SourceLocation Loc = Importer.Import(D->getLocation());
+
+ EmptyDecl *ToD = EmptyDecl::Create(Importer.getToContext(), DC, Loc);
+ ToD->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToD);
+ LexicalDC->addDeclInternal(ToD);
+ return ToD;
+}
+
Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
TranslationUnitDecl *ToD =
Importer.getToContext().getTranslationUnitDecl();
@@ -1410,6 +1497,44 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
return ToNamespace;
}
+Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+ // Import the major distinguishing characteristics of this namespace.
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *LookupD;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
+ return nullptr;
+ if (LookupD)
+ return LookupD;
+
+ // NOTE: No conflict resolution is done for namespace aliases now.
+
+ NamespaceDecl *TargetDecl = cast_or_null<NamespaceDecl>(
+ Importer.Import(D->getNamespace()));
+ if (!TargetDecl)
+ return nullptr;
+
+ IdentifierInfo *ToII = Importer.Import(D->getIdentifier());
+ if (!ToII)
+ return nullptr;
+
+ NestedNameSpecifierLoc ToQLoc = Importer.Import(D->getQualifierLoc());
+ if (D->getQualifierLoc() && !ToQLoc)
+ return nullptr;
+
+ NamespaceAliasDecl *ToD = NamespaceAliasDecl::Create(
+ Importer.getToContext(), DC, Importer.Import(D->getNamespaceLoc()),
+ Importer.Import(D->getAliasLoc()), ToII, ToQLoc,
+ Importer.Import(D->getTargetNameLoc()), TargetDecl);
+
+ ToD->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToD);
+ LexicalDC->addDeclInternal(ToD);
+
+ return ToD;
+}
+
Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
// Import the major distinguishing characteristics of this typedef.
DeclContext *DC, *LexicalDC;
@@ -1487,6 +1612,63 @@ Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
return VisitTypedefNameDecl(D, /*IsAlias=*/true);
}
+Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ // Import the major distinguishing characteristics of this typedef.
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ // If this typedef is not in block scope, determine whether we've
+ // seen a typedef with the same name (that we can merge with) or any
+ // other entity by that name (which name lookup could conflict with).
+ if (!DC->isFunctionOrMethod()) {
+ SmallVector<NamedDecl *, 4> ConflictingDecls;
+ unsigned IDNS = Decl::IDNS_Ordinary;
+ SmallVector<NamedDecl *, 2> FoundDecls;
+ DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
+ if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ continue;
+ if (auto *FoundAlias =
+ dyn_cast<TypeAliasTemplateDecl>(FoundDecls[I]))
+ return Importer.Imported(D, FoundAlias);
+ ConflictingDecls.push_back(FoundDecls[I]);
+ }
+
+ if (!ConflictingDecls.empty()) {
+ Name = Importer.HandleNameConflict(Name, DC, IDNS,
+ ConflictingDecls.data(),
+ ConflictingDecls.size());
+ if (!Name)
+ return nullptr;
+ }
+ }
+
+ TemplateParameterList *Params = ImportTemplateParameterList(
+ D->getTemplateParameters());
+ if (!Params)
+ return nullptr;
+
+ NamedDecl *TemplDecl = cast_or_null<NamedDecl>(
+ Importer.Import(D->getTemplatedDecl()));
+ if (!TemplDecl)
+ return nullptr;
+
+ TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create(
+ Importer.getToContext(), DC, Loc, Name, Params, TemplDecl);
+
+ ToAlias->setAccess(D->getAccess());
+ ToAlias->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToAlias);
+ LexicalDC->addDeclInternal(ToAlias);
+ return ToD;
+}
+
Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
// Import the major distinguishing characteristics of this label.
DeclContext *DC, *LexicalDC;
@@ -1752,6 +1934,31 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
}
D2 = D2CXX;
D2->setAccess(D->getAccess());
+
+ Importer.Imported(D, D2);
+
+ if (ClassTemplateDecl *FromDescribed =
+ DCXX->getDescribedClassTemplate()) {
+ ClassTemplateDecl *ToDescribed = cast_or_null<ClassTemplateDecl>(
+ Importer.Import(FromDescribed));
+ if (!ToDescribed)
+ return nullptr;
+ D2CXX->setDescribedClassTemplate(ToDescribed);
+
+ } else if (MemberSpecializationInfo *MemberInfo =
+ DCXX->getMemberSpecializationInfo()) {
+ TemplateSpecializationKind SK =
+ MemberInfo->getTemplateSpecializationKind();
+ CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass();
+ CXXRecordDecl *ToInst =
+ cast_or_null<CXXRecordDecl>(Importer.Import(FromInst));
+ if (FromInst && !ToInst)
+ return nullptr;
+ D2CXX->setInstantiationOfMemberClass(ToInst, SK);
+ D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
+ Importer.Import(MemberInfo->getPointOfInstantiation()));
+ }
+
} else {
D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
DC, StartLoc, Loc, Name.getAsIdentifierInfo());
@@ -1846,6 +2053,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (ToD)
return ToD;
+ const FunctionDecl *FoundWithoutBody = nullptr;
+
// Try to find a function in our own ("to") context with the same name, same
// type, and in the same context as the function we're importing.
if (!LexicalDC->isFunctionOrMethod()) {
@@ -1863,6 +2072,13 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundFunction->getType())) {
// FIXME: Actually try to merge the body and other attributes.
+ const FunctionDecl *FromBodyDecl = nullptr;
+ D->hasBody(FromBodyDecl);
+ if (D == FromBodyDecl && !FoundFunction->hasBody()) {
+ // This function is needed to merge completely.
+ FoundWithoutBody = FoundFunction;
+ break;
+ }
return Importer.Imported(D, FoundFunction);
}
@@ -2013,6 +2229,12 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
ToFunction->setParams(Parameters);
+ if (FoundWithoutBody) {
+ auto *Recent = const_cast<FunctionDecl *>(
+ FoundWithoutBody->getMostRecentDecl());
+ ToFunction->setPreviousDecl(Recent);
+ }
+
if (usedDifferentExceptionSpec) {
// Update FunctionProtoType::ExtProtoInfo.
QualType T = Importer.Import(D->getType());
@@ -2876,6 +3098,178 @@ Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
return ToLinkageSpec;
}
+Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD = nullptr;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ DeclarationNameInfo NameInfo(Name,
+ Importer.Import(D->getNameInfo().getLoc()));
+ ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+
+ UsingDecl *ToUsing = UsingDecl::Create(Importer.getToContext(), DC,
+ Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getQualifierLoc()),
+ NameInfo, D->hasTypename());
+ ToUsing->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(ToUsing);
+ Importer.Imported(D, ToUsing);
+
+ if (NamedDecl *FromPattern =
+ Importer.getFromContext().getInstantiatedFromUsingDecl(D)) {
+ if (NamedDecl *ToPattern =
+ dyn_cast_or_null<NamedDecl>(Importer.Import(FromPattern)))
+ Importer.getToContext().setInstantiatedFromUsingDecl(ToUsing, ToPattern);
+ else
+ return nullptr;
+ }
+
+ for (UsingShadowDecl *FromShadow : D->shadows()) {
+ if (UsingShadowDecl *ToShadow =
+ dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromShadow)))
+ ToUsing->addShadowDecl(ToShadow);
+ else
+ // FIXME: We return a nullptr here but the definition is already created
+ // and available with lookups. How to fix this?..
+ return nullptr;
+ }
+ return ToUsing;
+}
+
+Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD = nullptr;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ UsingDecl *ToUsing = dyn_cast_or_null<UsingDecl>(
+ Importer.Import(D->getUsingDecl()));
+ if (!ToUsing)
+ return nullptr;
+
+ NamedDecl *ToTarget = dyn_cast_or_null<NamedDecl>(
+ Importer.Import(D->getTargetDecl()));
+ if (!ToTarget)
+ return nullptr;
+
+ UsingShadowDecl *ToShadow = UsingShadowDecl::Create(
+ Importer.getToContext(), DC, Loc, ToUsing, ToTarget);
+
+ ToShadow->setLexicalDeclContext(LexicalDC);
+ ToShadow->setAccess(D->getAccess());
+ Importer.Imported(D, ToShadow);
+
+ if (UsingShadowDecl *FromPattern =
+ Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) {
+ if (UsingShadowDecl *ToPattern =
+ dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern)))
+ Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow,
+ ToPattern);
+ else
+ // FIXME: We return a nullptr here but the definition is already created
+ // and available with lookups. How to fix this?..
+ return nullptr;
+ }
+
+ LexicalDC->addDeclInternal(ToShadow);
+
+ return ToShadow;
+}
+
+
+Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD = nullptr;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ DeclContext *ToComAncestor = Importer.ImportContext(D->getCommonAncestor());
+ if (!ToComAncestor)
+ return nullptr;
+
+ NamespaceDecl *ToNominated = cast_or_null<NamespaceDecl>(
+ Importer.Import(D->getNominatedNamespace()));
+ if (!ToNominated)
+ return nullptr;
+
+ UsingDirectiveDecl *ToUsingDir = UsingDirectiveDecl::Create(
+ Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getNamespaceKeyLocation()),
+ Importer.Import(D->getQualifierLoc()),
+ Importer.Import(D->getIdentLocation()), ToNominated, ToComAncestor);
+ ToUsingDir->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(ToUsingDir);
+ Importer.Imported(D, ToUsingDir);
+
+ return ToUsingDir;
+}
+
+Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl(
+ UnresolvedUsingValueDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD = nullptr;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ DeclarationNameInfo NameInfo(Name, Importer.Import(D->getNameInfo().getLoc()));
+ ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+
+ UnresolvedUsingValueDecl *ToUsingValue = UnresolvedUsingValueDecl::Create(
+ Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getQualifierLoc()), NameInfo,
+ Importer.Import(D->getEllipsisLoc()));
+
+ Importer.Imported(D, ToUsingValue);
+ ToUsingValue->setAccess(D->getAccess());
+ ToUsingValue->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(ToUsingValue);
+
+ return ToUsingValue;
+}
+
+Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
+ UnresolvedUsingTypenameDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD = nullptr;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+ if (ToD)
+ return ToD;
+
+ UnresolvedUsingTypenameDecl *ToUsing = UnresolvedUsingTypenameDecl::Create(
+ Importer.getToContext(), DC, Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getTypenameLoc()),
+ Importer.Import(D->getQualifierLoc()), Loc, Name,
+ Importer.Import(D->getEllipsisLoc()));
+
+ Importer.Imported(D, ToUsing);
+ ToUsing->setAccess(D->getAccess());
+ ToUsing->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(ToUsing);
+
+ return ToUsing;
+}
+
+
bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
ObjCInterfaceDecl *To,
ImportDefinitionKind Kind) {
@@ -3453,7 +3847,6 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
CXXRecordDecl *DTemplated = D->getTemplatedDecl();
// Create the declaration that is being templated.
- // Create the declaration that is being templated.
CXXRecordDecl *D2Templated = cast_or_null<CXXRecordDecl>(
Importer.Import(DTemplated));
if (!D2Templated)
@@ -3560,11 +3953,10 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
TemplateArgumentListInfo ToTAInfo;
auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
for (unsigned I = 0, E = ASTTemplateArgs.NumTemplateArgs; I < E; ++I) {
- bool Error = false;
- auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I], Error);
- if (Error)
+ if (auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I]))
+ ToTAInfo.addArgument(*ToLoc);
+ else
return nullptr;
- ToTAInfo.addArgument(ToLoc);
}
QualType CanonInjType = Importer.Import(
@@ -3832,6 +4224,64 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
return D2;
}
+Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD;
+
+ if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return nullptr;
+
+ if (ToD)
+ return ToD;
+
+ // Try to find a function in our own ("to") context with the same name, same
+ // type, and in the same context as the function we're importing.
+ if (!LexicalDC->isFunctionOrMethod()) {
+ unsigned IDNS = Decl::IDNS_Ordinary;
+ SmallVector<NamedDecl *, 2> FoundDecls;
+ DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
+ if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ continue;
+
+ if (FunctionTemplateDecl *FoundFunction =
+ dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) {
+ if (FoundFunction->hasExternalFormalLinkage() &&
+ D->hasExternalFormalLinkage()) {
+ if (IsStructuralMatch(D, FoundFunction)) {
+ Importer.Imported(D, FoundFunction);
+ // FIXME: Actually try to merge the body and other attributes.
+ return FoundFunction;
+ }
+ }
+ }
+ }
+ }
+
+ TemplateParameterList *Params =
+ ImportTemplateParameterList(D->getTemplateParameters());
+ if (!Params)
+ return nullptr;
+
+ FunctionDecl *TemplatedFD =
+ cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl()));
+ if (!TemplatedFD)
+ return nullptr;
+
+ FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create(
+ Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD);
+
+ TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+ ToFunc->setAccess(D->getAccess());
+ ToFunc->setLexicalDeclContext(LexicalDC);
+ Importer.Imported(D, ToFunc);
+
+ LexicalDC->addDeclInternal(ToFunc);
+ return ToFunc;
+}
+
//----------------------------------------------------------------------------
// Import Statements
//----------------------------------------------------------------------------
@@ -3968,12 +4418,16 @@ Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
Expr *ToRHS = Importer.Import(S->getRHS());
if (!ToRHS && S->getRHS())
return nullptr;
+ Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
+ if (!ToSubStmt && S->getSubStmt())
+ return nullptr;
SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc());
SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc());
SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
- return new (Importer.getToContext()) CaseStmt(ToLHS, ToRHS,
- ToCaseLoc, ToEllipsisLoc,
- ToColonLoc);
+ CaseStmt *ToStmt = new (Importer.getToContext())
+ CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
+ ToStmt->setSubStmt(ToSubStmt);
+ return ToStmt;
}
Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
@@ -4443,11 +4897,10 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
TemplateArgumentListInfo *ResInfo = nullptr;
if (E->hasExplicitTemplateArgs()) {
for (const auto &FromLoc : E->template_arguments()) {
- bool Error = false;
- TemplateArgumentLoc ToTALoc = ImportTemplateArgumentLoc(FromLoc, Error);
- if (Error)
+ if (auto ToTALoc = ImportTemplateArgumentLoc(FromLoc))
+ ToTAInfo.addArgument(*ToTALoc);
+ else
return nullptr;
- ToTAInfo.addArgument(ToTALoc);
}
ResInfo = &ToTAInfo;
}
@@ -5161,6 +5614,20 @@ ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
return ToMTE;
}
+Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
+ QualType T = Importer.Import(E->getType());
+ if (T.isNull())
+ return nullptr;
+
+ Expr *Pattern = Importer.Import(E->getPattern());
+ if (!Pattern)
+ return nullptr;
+
+ return new (Importer.getToContext()) PackExpansionExpr(
+ T, Pattern, Importer.Import(E->getEllipsisLoc()),
+ E->getNumExpansions());
+}
+
Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
QualType T = Importer.Import(CE->getType());
if (T.isNull())
@@ -5344,6 +5811,80 @@ Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
E->getObjectKind());
}
+Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
+ CXXPseudoDestructorExpr *E) {
+
+ Expr *BaseE = Importer.Import(E->getBase());
+ if (!BaseE)
+ return nullptr;
+
+ TypeSourceInfo *ScopeInfo = Importer.Import(E->getScopeTypeInfo());
+ if (!ScopeInfo && E->getScopeTypeInfo())
+ return nullptr;
+
+ PseudoDestructorTypeStorage Storage;
+ if (IdentifierInfo *FromII = E->getDestroyedTypeIdentifier()) {
+ IdentifierInfo *ToII = Importer.Import(FromII);
+ if (!ToII)
+ return nullptr;
+ Storage = PseudoDestructorTypeStorage(
+ ToII, Importer.Import(E->getDestroyedTypeLoc()));
+ } else {
+ TypeSourceInfo *TI = Importer.Import(E->getDestroyedTypeInfo());
+ if (!TI)
+ return nullptr;
+ Storage = PseudoDestructorTypeStorage(TI);
+ }
+
+ return new (Importer.getToContext()) CXXPseudoDestructorExpr(
+ Importer.getToContext(), BaseE, E->isArrow(),
+ Importer.Import(E->getOperatorLoc()),
+ Importer.Import(E->getQualifierLoc()),
+ ScopeInfo, Importer.Import(E->getColonColonLoc()),
+ Importer.Import(E->getTildeLoc()), Storage);
+}
+
+Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
+ CXXDependentScopeMemberExpr *E) {
+ Expr *Base = nullptr;
+ if (!E->isImplicitAccess()) {
+ Base = Importer.Import(E->getBase());
+ if (!Base)
+ return nullptr;
+ }
+
+ QualType BaseType = Importer.Import(E->getBaseType());
+ if (BaseType.isNull())
+ return nullptr;
+
+ TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()),
+ Importer.Import(E->getRAngleLoc()));
+ TemplateArgumentListInfo *ResInfo = nullptr;
+ if (E->hasExplicitTemplateArgs()) {
+ if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+ return nullptr;
+ ResInfo = &ToTAInfo;
+ }
+
+ DeclarationName Name = Importer.Import(E->getMember());
+ if (!E->getMember().isEmpty() && Name.isEmpty())
+ return nullptr;
+
+ DeclarationNameInfo MemberNameInfo(Name, Importer.Import(E->getMemberLoc()));
+ // Import additional name location/type info.
+ ImportDeclarationNameLoc(E->getMemberNameInfo(), MemberNameInfo);
+ auto ToFQ = Importer.Import(E->getFirstQualifierFoundInScope());
+ if (!ToFQ && E->getFirstQualifierFoundInScope())
+ return nullptr;
+
+ return CXXDependentScopeMemberExpr::Create(
+ Importer.getToContext(), Base, BaseType, E->isArrow(),
+ Importer.Import(E->getOperatorLoc()),
+ Importer.Import(E->getQualifierLoc()),
+ Importer.Import(E->getTemplateKeywordLoc()),
+ cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
+}
+
Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
@@ -5510,6 +6051,26 @@ Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
Replacement);
}
+Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
+ QualType ToType = Importer.Import(E->getType());
+ if (ToType.isNull())
+ return nullptr;
+
+ SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs());
+ if (ImportContainerChecked(E->getArgs(), ToArgs))
+ return nullptr;
+
+ // According to Sema::BuildTypeTrait(), if E is value-dependent,
+ // Value is always false.
+ bool ToValue = false;
+ if (!E->isValueDependent())
+ ToValue = E->getValue();
+
+ return TypeTraitExpr::Create(
+ Importer.getToContext(), ToType, Importer.Import(E->getLocStart()),
+ E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue);
+}
+
void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index ea7faab767ed..0df8e5653f3b 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -365,6 +365,21 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
+ case Type::DependentAddressSpace: {
+ const DependentAddressSpaceType *DepAddressSpace1 =
+ cast<DependentAddressSpaceType>(T1);
+ const DependentAddressSpaceType *DepAddressSpace2 =
+ cast<DependentAddressSpaceType>(T2);
+ if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getAddrSpaceExpr(),
+ DepAddressSpace2->getAddrSpaceExpr()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getPointeeType(),
+ DepAddressSpace2->getPointeeType()))
+ return false;
+
+ break;
+ }
+
case Type::DependentSizedExtVector: {
const DependentSizedExtVectorType *Vec1 =
cast<DependentSizedExtVectorType>(T1);
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index ab9b59184294..a6f1027856c7 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -20,6 +20,7 @@ add_clang_library(clangAST
CommentLexer.cpp
CommentParser.cpp
CommentSema.cpp
+ DataCollection.cpp
Decl.cpp
DeclarationName.cpp
DeclBase.cpp
@@ -48,6 +49,7 @@ add_clang_library(clangAST
ODRHash.cpp
OpenMPClause.cpp
ParentMap.cpp
+ QualTypeNames.cpp
RawCommentList.cpp
RecordLayout.cpp
RecordLayoutBuilder.cpp
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index 924ef00e8147..06295b58178b 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -31,9 +31,16 @@ class CXXABI {
public:
virtual ~CXXABI();
- /// Returns the width and alignment of a member pointer in bits.
- virtual std::pair<uint64_t, unsigned>
- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const = 0;
+ struct MemberPointerInfo {
+ uint64_t Width;
+ unsigned Align;
+ bool HasPadding;
+ };
+
+ /// Returns the width and alignment of a member pointer in bits, as well as
+ /// whether it has padding.
+ virtual MemberPointerInfo
+ getMemberPointerInfo(const MemberPointerType *MPT) const = 0;
/// Returns the default calling convention for C++ methods.
virtual CallingConv getDefaultMethodCallConv(bool isVariadic) const = 0;
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index fc4d8b137337..24e96ba38015 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -1,4 +1,4 @@
-//===------ CXXInheritance.cpp - C++ Inheritance ----------------*- C++ -*-===//
+//===- CXXInheritance.cpp - C++ Inheritance -------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,13 +10,27 @@
// This file provides routines that help analyzing C++ inheritance hierarchies.
//
//===----------------------------------------------------------------------===//
+
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/RecordLayout.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
#include <algorithm>
+#include <utility>
+#include <cassert>
+#include <vector>
using namespace clang;
@@ -26,7 +40,7 @@ void CXXBasePaths::ComputeDeclsFound() {
assert(NumDeclsFound == 0 && !DeclsFound &&
"Already computed the set of declarations");
- llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8> > Decls;
+ llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8>> Decls;
for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path)
Decls.insert(Path->Decls.front());
@@ -419,8 +433,8 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path,
DeclarationName Name) {
- const unsigned IDNS = clang::Decl::IDNS_Ordinary | clang::Decl::IDNS_Tag |
- clang::Decl::IDNS_Member;
+ const unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag |
+ Decl::IDNS_Member;
for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
@@ -550,26 +564,27 @@ void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) {
}
}
-
namespace {
- class FinalOverriderCollector {
- /// \brief The number of subobjects of a given class type that
- /// occur within the class hierarchy.
- llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
- /// \brief Overriders for each virtual base subobject.
- llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
+class FinalOverriderCollector {
+ /// \brief The number of subobjects of a given class type that
+ /// occur within the class hierarchy.
+ llvm::DenseMap<const CXXRecordDecl *, unsigned> SubobjectCount;
- CXXFinalOverriderMap FinalOverriders;
+ /// \brief Overriders for each virtual base subobject.
+ llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
- public:
- ~FinalOverriderCollector();
+ CXXFinalOverriderMap FinalOverriders;
- void Collect(const CXXRecordDecl *RD, bool VirtualBase,
- const CXXRecordDecl *InVirtualSubobject,
- CXXFinalOverriderMap &Overriders);
- };
-}
+public:
+ ~FinalOverriderCollector();
+
+ void Collect(const CXXRecordDecl *RD, bool VirtualBase,
+ const CXXRecordDecl *InVirtualSubobject,
+ CXXFinalOverriderMap &Overriders);
+};
+
+} // namespace
void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
bool VirtualBase,
@@ -635,9 +650,11 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
continue;
CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
+ using OverriddenMethodsRange =
+ llvm::iterator_range<CXXMethodDecl::method_iterator>;
+ OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods();
- if (CanonM->begin_overridden_methods()
- == CanonM->end_overridden_methods()) {
+ if (OverriddenMethods.begin() == OverriddenMethods.end()) {
// This is a new virtual function that does not override any
// other virtual function. Add it to the map of virtual
// functions for which we are tracking overridders.
@@ -656,11 +673,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
// overrider. To do so, we dig down to the original virtual
// functions using data recursion and update all of the methods it
// overrides.
- typedef llvm::iterator_range<CXXMethodDecl::method_iterator>
- OverriddenMethods;
- SmallVector<OverriddenMethods, 4> Stack;
- Stack.push_back(llvm::make_range(CanonM->begin_overridden_methods(),
- CanonM->end_overridden_methods()));
+ SmallVector<OverriddenMethodsRange, 4> Stack(1, OverriddenMethods);
while (!Stack.empty()) {
for (const CXXMethodDecl *OM : Stack.pop_back_val()) {
const CXXMethodDecl *CanonOM = OM->getCanonicalDecl();
@@ -678,14 +691,13 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
UniqueVirtualMethod(CanonM, SubobjectNumber,
InVirtualSubobject));
- if (CanonOM->begin_overridden_methods()
- == CanonOM->end_overridden_methods())
+ auto OverriddenMethods = CanonOM->overridden_methods();
+ if (OverriddenMethods.begin() == OverriddenMethods.end())
continue;
// Continue recursion to the methods that this virtual method
// overrides.
- Stack.push_back(llvm::make_range(CanonOM->begin_overridden_methods(),
- CanonOM->end_overridden_methods()));
+ Stack.push_back(OverriddenMethods);
}
}
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 403454d3ab7e..6c2019e1a72b 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -813,7 +813,7 @@ bool Sema::isAnyFunctionDecl() {
}
bool Sema::isFunctionOrMethodVariadic() {
- if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl())
+ if (!isFunctionDecl() || !ThisDeclInfo->CurrentDecl)
return false;
if (const FunctionDecl *FD =
dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl))
@@ -824,6 +824,14 @@ bool Sema::isFunctionOrMethodVariadic() {
if (const ObjCMethodDecl *MD =
dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
return MD->isVariadic();
+ if (const TypedefNameDecl *TD =
+ dyn_cast<TypedefNameDecl>(ThisDeclInfo->CurrentDecl)) {
+ QualType Type = TD->getUnderlyingType();
+ if (Type->isFunctionPointerType() || Type->isBlockPointerType())
+ Type = Type->getPointeeType();
+ if (const auto *FT = Type->getAs<FunctionProtoType>())
+ return FT->isVariadic();
+ }
return false;
}
diff --git a/lib/AST/DataCollection.cpp b/lib/AST/DataCollection.cpp
new file mode 100644
index 000000000000..c2ecabe8e6f8
--- /dev/null
+++ b/lib/AST/DataCollection.cpp
@@ -0,0 +1,50 @@
+//===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DataCollection.h"
+
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+namespace data_collection {
+
+/// Prints the macro name that contains the given SourceLocation into the given
+/// raw_string_ostream.
+static void printMacroName(llvm::raw_string_ostream &MacroStack,
+ ASTContext &Context, SourceLocation Loc) {
+ MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
+ Context.getLangOpts());
+
+ // Add an empty space at the end as a padding to prevent
+ // that macro names concatenate to the names of other macros.
+ MacroStack << " ";
+}
+
+/// Returns a string that represents all macro expansions that expanded into the
+/// given SourceLocation.
+///
+/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
+/// A and B are expanded from the same macros in the same order.
+std::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
+ std::string MacroStack;
+ llvm::raw_string_ostream MacroStackStream(MacroStack);
+ SourceManager &SM = Context.getSourceManager();
+
+ // Iterate over all macros that expanded into the given SourceLocation.
+ while (Loc.isMacroID()) {
+ // Add the macro name to the stream.
+ printMacroName(MacroStackStream, Context, Loc);
+ Loc = SM.getImmediateMacroCallerLoc(Loc);
+ }
+ MacroStackStream.flush();
+ return MacroStack;
+}
+
+} // end namespace data_collection
+} // end namespace clang
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 573a98efe980..2f51ec31a7bd 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1,4 +1,4 @@
-//===--- Decl.cpp - Declaration AST Node Implementation -------------------===//
+//===- Decl.cpp - Declaration AST Node Implementation ---------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,27 +12,62 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/Decl.h"
+#include "Linkage.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
-#include "clang/AST/Attr.h"
+#include "clang/AST/CanonicalType.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Redeclarable.h"
#include "clang/AST/Stmt.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Linkage.h"
#include "clang/Basic/Module.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SanitizerBlacklist.h"
+#include "clang/Basic/Sanitizers.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Visibility.h"
#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <memory>
+#include <string>
+#include <tuple>
+#include <type_traits>
using namespace clang;
@@ -47,7 +82,7 @@ bool Decl::isOutOfLine() const {
TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
: Decl(TranslationUnit, nullptr, SourceLocation()),
- DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) {}
+ DeclContext(TranslationUnit), Ctx(ctx) {}
//===----------------------------------------------------------------------===//
// NamedDecl Implementation
@@ -99,63 +134,25 @@ TranslationUnitDecl::TranslationUnitDecl(ASTContext &ctx)
// and 'matcher' is a type only matters when looking for attributes
// and settings from the immediate context.
-const unsigned IgnoreExplicitVisibilityBit = 2;
-const unsigned IgnoreAllVisibilityBit = 4;
-
-/// Kinds of LV computation. The linkage side of the computation is
-/// always the same, but different things can change how visibility is
-/// computed.
-enum LVComputationKind {
- /// Do an LV computation for, ultimately, a type.
- /// Visibility may be restricted by type visibility settings and
- /// the visibility of template arguments.
- LVForType = NamedDecl::VisibilityForType,
-
- /// Do an LV computation for, ultimately, a non-type declaration.
- /// Visibility may be restricted by value visibility settings and
- /// the visibility of template arguments.
- LVForValue = NamedDecl::VisibilityForValue,
-
- /// Do an LV computation for, ultimately, a type that already has
- /// some sort of explicit visibility. Visibility may only be
- /// restricted by the visibility of template arguments.
- LVForExplicitType = (LVForType | IgnoreExplicitVisibilityBit),
-
- /// Do an LV computation for, ultimately, a non-type declaration
- /// that already has some sort of explicit visibility. Visibility
- /// may only be restricted by the visibility of template arguments.
- LVForExplicitValue = (LVForValue | IgnoreExplicitVisibilityBit),
-
- /// Do an LV computation when we only care about the linkage.
- LVForLinkageOnly =
- LVForValue | IgnoreExplicitVisibilityBit | IgnoreAllVisibilityBit
-};
-
/// Does this computation kind permit us to consider additional
/// visibility settings from attributes and the like?
static bool hasExplicitVisibilityAlready(LVComputationKind computation) {
- return ((unsigned(computation) & IgnoreExplicitVisibilityBit) != 0);
+ return computation.IgnoreExplicitVisibility;
}
/// Given an LVComputationKind, return one of the same type/value sort
/// that records that it already has explicit visibility.
static LVComputationKind
-withExplicitVisibilityAlready(LVComputationKind oldKind) {
- LVComputationKind newKind =
- static_cast<LVComputationKind>(unsigned(oldKind) |
- IgnoreExplicitVisibilityBit);
- assert(oldKind != LVForType || newKind == LVForExplicitType);
- assert(oldKind != LVForValue || newKind == LVForExplicitValue);
- assert(oldKind != LVForExplicitType || newKind == LVForExplicitType);
- assert(oldKind != LVForExplicitValue || newKind == LVForExplicitValue);
- return newKind;
+withExplicitVisibilityAlready(LVComputationKind Kind) {
+ Kind.IgnoreExplicitVisibility = true;
+ return Kind;
}
static Optional<Visibility> getExplicitVisibility(const NamedDecl *D,
LVComputationKind kind) {
- assert(!hasExplicitVisibilityAlready(kind) &&
+ assert(!kind.IgnoreExplicitVisibility &&
"asking for explicit visibility when we shouldn't be");
- return D->getExplicitVisibility((NamedDecl::ExplicitVisibilityKind) kind);
+ return D->getExplicitVisibility(kind.getExplicitVisibilityKind());
}
/// Is the given declaration a "type" or a "value" for the purposes of
@@ -216,30 +213,21 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
return getVisibilityFromAttr(A);
}
- // If we're on Mac OS X, an 'availability' for Mac OS X attribute
- // implies visibility(default).
- if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
- for (const auto *A : D->specific_attrs<AvailabilityAttr>())
- if (A->getPlatform()->getName().equals("macos"))
- return DefaultVisibility;
- }
-
return None;
}
-static LinkageInfo
-getLVForType(const Type &T, LVComputationKind computation) {
- if (computation == LVForLinkageOnly)
+LinkageInfo LinkageComputer::getLVForType(const Type &T,
+ LVComputationKind computation) {
+ if (computation.IgnoreAllVisibility)
return LinkageInfo(T.getLinkage(), DefaultVisibility, true);
- return T.getLinkageAndVisibility();
+ return getTypeLinkageAndVisibility(&T);
}
/// \brief Get the most restrictive linkage for the types in the given
/// template parameter list. For visibility purposes, template
/// parameters are part of the signature of a template.
-static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *Params,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForTemplateParameterList(
+ const TemplateParameterList *Params, LVComputationKind computation) {
LinkageInfo LV;
for (const NamedDecl *P : *Params) {
// Template type parameters are the most common and never
@@ -264,7 +252,7 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
for (unsigned i = 0, n = NTTP->getNumExpansionTypes(); i != n; ++i) {
QualType type = NTTP->getExpansionType(i);
if (!type->isDependentType())
- LV.merge(type->getLinkageAndVisibility());
+ LV.merge(getTypeLinkageAndVisibility(type));
}
continue;
}
@@ -291,10 +279,6 @@ getLVForTemplateParameterList(const TemplateParameterList *Params,
return LV;
}
-/// getLVForDecl - Get the linkage and visibility for the given declaration.
-static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation);
-
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
const Decl *Ret = nullptr;
const DeclContext *DC = D->getDeclContext();
@@ -311,8 +295,9 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
///
/// Note that we don't take an LVComputationKind because we always
/// want to honor the visibility of template arguments in the same way.
-static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+ LVComputationKind computation) {
LinkageInfo LV;
for (const TemplateArgument &Arg : Args) {
@@ -334,7 +319,7 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
continue;
case TemplateArgument::NullPtr:
- LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
+ LV.merge(getTypeLinkageAndVisibility(Arg.getNullPtrType()));
continue;
case TemplateArgument::Template:
@@ -354,9 +339,9 @@ static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
return LV;
}
-static LinkageInfo
-getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
+ LVComputationKind computation) {
return getLVForTemplateArgumentList(TArgs.asArray(), computation);
}
@@ -379,10 +364,10 @@ static bool shouldConsiderTemplateVisibility(const FunctionDecl *fn,
/// LVForValue.
///
/// \param[out] LV the computation to use for the parent
-static void
-mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
- const FunctionTemplateSpecializationInfo *specInfo,
- LVComputationKind computation) {
+void LinkageComputer::mergeTemplateLV(
+ LinkageInfo &LV, const FunctionDecl *fn,
+ const FunctionTemplateSpecializationInfo *specInfo,
+ LVComputationKind computation) {
bool considerVisibility =
shouldConsiderTemplateVisibility(fn, specInfo);
@@ -402,21 +387,11 @@ mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
/// that would match the given rules?
static bool hasDirectVisibilityAttribute(const NamedDecl *D,
LVComputationKind computation) {
- switch (computation) {
- case LVForType:
- case LVForExplicitType:
- if (D->hasAttr<TypeVisibilityAttr>())
- return true;
- // fallthrough
- case LVForValue:
- case LVForExplicitValue:
- if (D->hasAttr<VisibilityAttr>())
- return true;
+ if (computation.IgnoreAllVisibility)
return false;
- case LVForLinkageOnly:
- return false;
- }
- llvm_unreachable("bad visibility computation kind");
+
+ return (computation.isTypeVisibility() && D->hasAttr<TypeVisibilityAttr>()) ||
+ D->hasAttr<VisibilityAttr>();
}
/// Should we consider visibility associated with the template
@@ -457,9 +432,9 @@ static bool shouldConsiderTemplateVisibility(
/// Merge in template-related linkage and visibility for the given
/// class template specialization.
-static void mergeTemplateLV(LinkageInfo &LV,
- const ClassTemplateSpecializationDecl *spec,
- LVComputationKind computation) {
+void LinkageComputer::mergeTemplateLV(
+ LinkageInfo &LV, const ClassTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
// Merge information from the template parameters, but ignore
@@ -509,9 +484,9 @@ static bool shouldConsiderTemplateVisibility(
/// Merge in template-related linkage and visibility for the given
/// variable template specialization. As usual, follow class template
/// specialization logic up to initialization.
-static void mergeTemplateLV(LinkageInfo &LV,
- const VarTemplateSpecializationDecl *spec,
- LVComputationKind computation) {
+void LinkageComputer::mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
// Merge information from the template parameters, but ignore
@@ -574,6 +549,7 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
}
static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
+ // FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
case Decl::ModuleOwnershipKind::Unowned:
case Decl::ModuleOwnershipKind::ModulePrivate:
@@ -605,14 +581,17 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
// declaration has module linkage.
if (auto *M = D->getOwningModule())
if (M->Kind == Module::ModuleInterfaceUnit)
- if (!isExportedFromModuleIntefaceUnit(D))
+ if (!isExportedFromModuleIntefaceUnit(
+ cast<NamedDecl>(D->getCanonicalDecl())))
return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
return LinkageInfo::external();
}
-static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
@@ -652,7 +631,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
PrevVar = PrevVar->getPreviousDecl()) {
if (PrevVar->getStorageClass() == SC_PrivateExtern &&
Var->getStorageClass() == SC_None)
- return PrevVar->getLinkageAndVisibility();
+ return getDeclLinkageAndVisibility(PrevVar);
// Explicitly declared static.
if (PrevVar->getStorageClass() == SC_Static)
return getInternalLinkageFor(Var);
@@ -669,23 +648,23 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// - a data member of an anonymous union.
const VarDecl *VD = IFD->getVarDecl();
assert(VD && "Expected a VarDecl in this IndirectFieldDecl!");
- return getLVForNamespaceScopeDecl(VD, computation);
+ return getLVForNamespaceScopeDecl(VD, computation, IgnoreVarTypeLinkage);
}
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
if (D->isInAnonymousNamespace()) {
const auto *Var = dyn_cast<VarDecl>(D);
const auto *Func = dyn_cast<FunctionDecl>(D);
- // FIXME: In C++11 onwards, anonymous namespaces should give decls
- // within them (including those inside extern "C" contexts) internal
- // linkage, not unique external linkage:
+ // FIXME: The check for extern "C" here is not justified by the standard
+ // wording, but we retain it from the pre-DR1113 model to avoid breaking
+ // code.
//
// C++11 [basic.link]p4:
// An unnamed namespace or a namespace declared directly or indirectly
// within an unnamed namespace has internal linkage.
if ((!Var || !isFirstInExternCContext(Var)) &&
(!Func || !isFirstInExternCContext(Func)))
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(D);
}
// Set up the defaults.
@@ -694,7 +673,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// If the declaration of an identifier for an object has file
// scope and no storage-class specifier, its linkage is
// external.
- LinkageInfo LV;
+ LinkageInfo LV = getExternalLinkageFor(D);
if (!hasExplicitVisibilityAlready(computation)) {
if (Optional<Visibility> Vis = getExplicitVisibility(D, computation)) {
@@ -717,13 +696,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// Add in global settings if the above didn't give us direct visibility.
if (!LV.isVisibilityExplicit()) {
// Use global type/value visibility as appropriate.
- Visibility globalVisibility;
- if (computation == LVForValue) {
- globalVisibility = Context.getLangOpts().getValueVisibilityMode();
- } else {
- assert(computation == LVForType);
- globalVisibility = Context.getLangOpts().getTypeVisibilityMode();
- }
+ Visibility globalVisibility =
+ computation.isValueVisibility()
+ ? Context.getLangOpts().getValueVisibilityMode()
+ : Context.getLangOpts().getTypeVisibilityMode();
LV.mergeVisibility(globalVisibility, /*explicit*/ false);
// If we're paying attention to global visibility, apply
@@ -761,10 +737,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
//
// Note that we don't want to make the variable non-external
// because of this, but unique-external linkage suits us.
- if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var)) {
+ if (Context.getLangOpts().CPlusPlus && !isFirstInExternCContext(Var) &&
+ !IgnoreVarTypeLinkage) {
LinkageInfo TypeLV = getLVForType(*Var->getType(), computation);
- if (TypeLV.getLinkage() != ExternalLinkage &&
- TypeLV.getLinkage() != ModuleLinkage)
+ if (!isExternallyVisible(TypeLV.getLinkage()))
return LinkageInfo::uniqueExternal();
if (!LV.isVisibilityExplicit())
LV.mergeVisibility(TypeLV);
@@ -802,19 +778,13 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// unique-external linkage, it's not legally usable from outside
// this translation unit. However, we should use the C linkage
// rules instead for extern "C" declarations.
- if (Context.getLangOpts().CPlusPlus &&
- !Function->isInExternCContext()) {
- // Only look at the type-as-written. If this function has an auto-deduced
- // return type, we can't compute the linkage of that type because it could
- // require looking at the linkage of this function, and we don't need this
- // for correctness because the type is not part of the function's
- // signature.
- // FIXME: This is a hack. We should be able to solve this circularity and
- // the one in getLVForClassMember for Functions some other way.
+ if (Context.getLangOpts().CPlusPlus && !Function->isInExternCContext()) {
+ // Only look at the type-as-written. Otherwise, deducing the return type
+ // of a function could change its linkage.
QualType TypeAsWritten = Function->getType();
if (TypeSourceInfo *TSI = Function->getTypeSourceInfo())
TypeAsWritten = TSI->getType();
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
+ if (!isExternallyVisible(TypeAsWritten->getLinkage()))
return LinkageInfo::uniqueExternal();
}
@@ -883,16 +853,18 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
return LinkageInfo::none();
}
- // If we ended up with non-external linkage, visibility should
+ // If we ended up with non-externally-visible linkage, visibility should
// always be default.
- if (LV.getLinkage() != ExternalLinkage)
+ if (!isExternallyVisible(LV.getLinkage()))
return LinkageInfo(LV.getLinkage(), DefaultVisibility, false);
return LV;
}
-static LinkageInfo getLVForClassMember(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo
+LinkageComputer::getLVForClassMember(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
// Only certain class members have linkage. Note that fields don't
// really have linkage, but it's convenient to say they do for the
// purposes of calculating linkage of pointer-to-data-member
@@ -935,12 +907,11 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
LinkageInfo classLV =
getLVForDecl(cast<RecordDecl>(D->getDeclContext()), classComputation);
- // If the class already has unique-external linkage, we can't improve.
- if (classLV.getLinkage() == UniqueExternalLinkage)
- return LinkageInfo::uniqueExternal();
-
+ // The member has the same linkage as the class. If that's not externally
+ // visible, we don't need to compute anything about the linkage.
+ // FIXME: If we're only computing linkage, can we bail out here?
if (!isExternallyVisible(classLV.getLinkage()))
- return LinkageInfo::none();
+ return classLV;
// Otherwise, don't merge in classLV yet, because in certain cases
@@ -950,22 +921,14 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
const NamedDecl *explicitSpecSuppressor = nullptr;
if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
- // If the type of the function uses a type with unique-external
- // linkage, it's not legally usable from outside this translation unit.
- // But only look at the type-as-written. If this function has an
- // auto-deduced return type, we can't compute the linkage of that type
- // because it could require looking at the linkage of this function, and we
- // don't need this for correctness because the type is not part of the
- // function's signature.
- // FIXME: This is a hack. We should be able to solve this circularity and
- // the one in getLVForNamespaceScopeDecl for Functions some other way.
- {
- QualType TypeAsWritten = MD->getType();
- if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
- TypeAsWritten = TSI->getType();
- if (TypeAsWritten->getLinkage() == UniqueExternalLinkage)
- return LinkageInfo::uniqueExternal();
- }
+ // Only look at the type-as-written. Otherwise, deducing the return type
+ // of a function could change its linkage.
+ QualType TypeAsWritten = MD->getType();
+ if (TypeSourceInfo *TSI = MD->getTypeSourceInfo())
+ TypeAsWritten = TSI->getType();
+ if (!isExternallyVisible(TypeAsWritten->getLinkage()))
+ return LinkageInfo::uniqueExternal();
+
// If this is a method template specialization, use the linkage for
// the template parameters and arguments.
if (FunctionTemplateSpecializationInfo *spec
@@ -1002,10 +965,14 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
- LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
- if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
- LV.mergeVisibility(typeLV);
- LV.mergeExternalVisibility(typeLV);
+ if (!IgnoreVarTypeLinkage) {
+ LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
+ // FIXME: If the type's linkage is not externally visible, we can
+ // give this static data member UniqueExternalLinkage.
+ if (!LV.isVisibilityExplicit() && !classLV.isVisibilityExplicit())
+ LV.mergeVisibility(typeLV);
+ LV.mergeExternalVisibility(typeLV);
+ }
if (isExplicitMemberSpecialization(VD)) {
explicitSpecSuppressor = VD;
@@ -1047,17 +1014,16 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
return LV;
}
-void NamedDecl::anchor() { }
-
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
- LVComputationKind computation);
+void NamedDecl::anchor() {}
bool NamedDecl::isLinkageValid() const {
if (!hasCachedLinkage())
return true;
- return computeLVForDecl(this, LVForLinkageOnly).getLinkage() ==
- getCachedLinkage();
+ Linkage L = LinkageComputer{}
+ .computeLVForDecl(this, LVComputationKind::forLinkageOnly())
+ .getLinkage();
+ return L == getCachedLinkage();
}
ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
@@ -1076,13 +1042,13 @@ ObjCStringFormatFamily NamedDecl::getObjCFStringFormattingFamily() const {
Linkage NamedDecl::getLinkageInternal() const {
// We don't care about visibility here, so ask for the cheapest
// possible visibility analysis.
- return getLVForDecl(this, LVForLinkageOnly).getLinkage();
+ return LinkageComputer{}
+ .getLVForDecl(this, LVComputationKind::forLinkageOnly())
+ .getLinkage();
}
LinkageInfo NamedDecl::getLinkageAndVisibility() const {
- LVComputationKind computation =
- (usesTypeVisibility(this) ? LVForType : LVForValue);
- return getLVForDecl(this, computation);
+ return LinkageComputer{}.getDeclLinkageAndVisibility(this);
}
static Optional<Visibility>
@@ -1160,30 +1126,46 @@ NamedDecl::getExplicitVisibility(ExplicitVisibilityKind kind) const {
return getExplicitVisibilityAux(this, kind, false);
}
-static LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForClosure(const DeclContext *DC,
+ Decl *ContextDecl,
+ LVComputationKind computation) {
// This lambda has its linkage/visibility determined by its owner.
- if (ContextDecl) {
- if (isa<ParmVarDecl>(ContextDecl))
- DC = ContextDecl->getDeclContext()->getRedeclContext();
- else
- return getLVForDecl(cast<NamedDecl>(ContextDecl), computation);
- }
+ const NamedDecl *Owner;
+ if (!ContextDecl)
+ Owner = dyn_cast<NamedDecl>(DC);
+ else if (isa<ParmVarDecl>(ContextDecl))
+ Owner =
+ dyn_cast<NamedDecl>(ContextDecl->getDeclContext()->getRedeclContext());
+ else
+ Owner = cast<NamedDecl>(ContextDecl);
- if (const auto *ND = dyn_cast<NamedDecl>(DC))
- return getLVForDecl(ND, computation);
+ if (!Owner)
+ return LinkageInfo::none();
- // FIXME: We have a closure at TU scope with no context declaration. This
- // should probably have no linkage.
- return LinkageInfo::external();
+ // If the owner has a deduced type, we need to skip querying the linkage and
+ // visibility of that type, because it might involve this closure type. The
+ // only effect of this is that we might give a lambda VisibleNoLinkage rather
+ // than NoLinkage when we don't strictly need to, which is benign.
+ auto *VD = dyn_cast<VarDecl>(Owner);
+ LinkageInfo OwnerLV =
+ VD && VD->getType()->getContainedDeducedType()
+ ? computeLVForDecl(Owner, computation, /*IgnoreVarTypeLinkage*/true)
+ : getLVForDecl(Owner, computation);
+
+ // A lambda never formally has linkage. But if the owner is externally
+ // visible, then the lambda is too. We apply the same rules to blocks.
+ if (!isExternallyVisible(OwnerLV.getLinkage()))
+ return LinkageInfo::none();
+ return LinkageInfo(VisibleNoLinkage, OwnerLV.getVisibility(),
+ OwnerLV.isVisibilityExplicit());
}
-static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::getLVForLocalDecl(const NamedDecl *D,
+ LVComputationKind computation) {
if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
if (Function->isInAnonymousNamespace() &&
!Function->isInExternCContext())
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(Function);
// This is a "void f();" which got merged with a file static.
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -1206,7 +1188,7 @@ static LinkageInfo getLVForLocalDecl(const NamedDecl *D,
if (const auto *Var = dyn_cast<VarDecl>(D)) {
if (Var->hasExternalStorage()) {
if (Var->isInAnonymousNamespace() && !Var->isInExternCContext())
- return LinkageInfo::uniqueExternal();
+ return getInternalLinkageFor(Var);
LinkageInfo LV;
if (Var->getStorageClass() == SC_PrivateExtern)
@@ -1272,8 +1254,9 @@ getOutermostEnclosingLambda(const CXXRecordDecl *Record) {
return Ret;
}
-static LinkageInfo computeLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
+LinkageInfo LinkageComputer::computeLVForDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage) {
// Internal_linkage attribute overrides other considerations.
if (D->hasAttr<InternalLinkageAttr>())
return getInternalLinkageFor(D);
@@ -1361,7 +1344,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
// Handle linkage for namespace-scope names.
if (D->getDeclContext()->getRedeclContext()->isFileContext())
- return getLVForNamespaceScopeDecl(D, computation);
+ return getLVForNamespaceScopeDecl(D, computation, IgnoreVarTypeLinkage);
// C++ [basic.link]p5:
// In addition, a member function, static data member, a named
@@ -1371,7 +1354,7 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
// purposes (7.1.3), has external linkage if the name of the class
// has external linkage.
if (D->getDeclContext()->isRecord())
- return getLVForClassMember(D, computation);
+ return getLVForClassMember(D, computation, IgnoreVarTypeLinkage);
// C++ [basic.link]p6:
// The name of a function declared in block scope and the name of
@@ -1392,56 +1375,93 @@ static LinkageInfo computeLVForDecl(const NamedDecl *D,
return LinkageInfo::none();
}
-namespace clang {
-class LinkageComputer {
-public:
- static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
- // Internal_linkage attribute overrides other considerations.
- if (D->hasAttr<InternalLinkageAttr>())
- return getInternalLinkageFor(D);
+/// getLVForDecl - Get the linkage and visibility for the given declaration.
+LinkageInfo LinkageComputer::getLVForDecl(const NamedDecl *D,
+ LVComputationKind computation) {
+ // Internal_linkage attribute overrides other considerations.
+ if (D->hasAttr<InternalLinkageAttr>())
+ return getInternalLinkageFor(D);
+
+ if (computation.IgnoreAllVisibility && D->hasCachedLinkage())
+ return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
- if (computation == LVForLinkageOnly && D->hasCachedLinkage())
- return LinkageInfo(D->getCachedLinkage(), DefaultVisibility, false);
+ if (llvm::Optional<LinkageInfo> LI = lookup(D, computation))
+ return *LI;
- LinkageInfo LV = computeLVForDecl(D, computation);
- if (D->hasCachedLinkage())
- assert(D->getCachedLinkage() == LV.getLinkage());
+ LinkageInfo LV = computeLVForDecl(D, computation);
+ if (D->hasCachedLinkage())
+ assert(D->getCachedLinkage() == LV.getLinkage());
- D->setCachedLinkage(LV.getLinkage());
+ D->setCachedLinkage(LV.getLinkage());
+ cache(D, computation, LV);
#ifndef NDEBUG
- // In C (because of gnu inline) and in c++ with microsoft extensions an
- // static can follow an extern, so we can have two decls with different
- // linkages.
- const LangOptions &Opts = D->getASTContext().getLangOpts();
- if (!Opts.CPlusPlus || Opts.MicrosoftExt)
- return LV;
+ // In C (because of gnu inline) and in c++ with microsoft extensions an
+ // static can follow an extern, so we can have two decls with different
+ // linkages.
+ const LangOptions &Opts = D->getASTContext().getLangOpts();
+ if (!Opts.CPlusPlus || Opts.MicrosoftExt)
+ return LV;
- // We have just computed the linkage for this decl. By induction we know
- // that all other computed linkages match, check that the one we just
- // computed also does.
- NamedDecl *Old = nullptr;
- for (auto I : D->redecls()) {
- auto *T = cast<NamedDecl>(I);
- if (T == D)
- continue;
- if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
- Old = T;
- break;
- }
+ // We have just computed the linkage for this decl. By induction we know
+ // that all other computed linkages match, check that the one we just
+ // computed also does.
+ NamedDecl *Old = nullptr;
+ for (auto I : D->redecls()) {
+ auto *T = cast<NamedDecl>(I);
+ if (T == D)
+ continue;
+ if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
+ Old = T;
+ break;
}
- assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
+ }
+ assert(!Old || Old->getCachedLinkage() == D->getCachedLinkage());
#endif
- return LV;
- }
-};
+ return LV;
}
-static LinkageInfo getLVForDecl(const NamedDecl *D,
- LVComputationKind computation) {
- return clang::LinkageComputer::getLVForDecl(D, computation);
+LinkageInfo LinkageComputer::getDeclLinkageAndVisibility(const NamedDecl *D) {
+ return getLVForDecl(D,
+ LVComputationKind(usesTypeVisibility(D)
+ ? NamedDecl::VisibilityForType
+ : NamedDecl::VisibilityForValue));
+}
+
+Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
+ Module *M = getOwningModule();
+ if (!M)
+ return nullptr;
+
+ switch (M->Kind) {
+ case Module::ModuleMapModule:
+ // Module map modules have no special linkage semantics.
+ return nullptr;
+
+ case Module::ModuleInterfaceUnit:
+ return M;
+
+ case Module::GlobalModuleFragment: {
+ // External linkage declarations in the global module have no owning module
+ // for linkage purposes. But internal linkage declarations in the global
+ // module fragment of a particular module are owned by that module for
+ // linkage purposes.
+ if (IgnoreLinkage)
+ return nullptr;
+ bool InternalLinkage;
+ if (auto *ND = dyn_cast<NamedDecl>(this))
+ InternalLinkage = !ND->hasExternalFormalLinkage();
+ else {
+ auto *NSD = dyn_cast<NamespaceDecl>(this);
+ InternalLinkage = (NSD && NSD->isAnonymousNamespace()) ||
+ isInAnonymousNamespace();
+ }
+ return InternalLinkage ? M->Parent : nullptr;
+ }
+ }
+
+ llvm_unreachable("unknown module kind");
}
void NamedDecl::printName(raw_ostream &os) const {
@@ -1473,7 +1493,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
return;
}
- typedef SmallVector<const DeclContext *, 8> ContextsTy;
+ using ContextsTy = SmallVector<const DeclContext *, 8>;
ContextsTy Contexts;
// Collect contexts.
@@ -1482,12 +1502,11 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
Ctx = Ctx->getParent();
}
- for (const DeclContext *DC : reverse(Contexts)) {
+ for (const DeclContext *DC : llvm::reverse(Contexts)) {
if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
OS << Spec->getName();
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs.asArray(), P);
+ printTemplateArgumentList(OS, TemplateArgs.asArray(), P);
} else if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
if (P.SuppressUnwrittenScope &&
(ND->isAnonymousNamespace() || ND->isInline()))
@@ -1612,14 +1631,6 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD, bool IsKnownNewer) const {
cast<UnresolvedUsingValueDecl>(OldD)->getQualifier());
}
- // UsingDirectiveDecl's are not really NamedDecl's, and all have same name.
- // They can be replaced if they nominate the same namespace.
- // FIXME: Is this true even if they have different module visibility?
- if (auto *UD = dyn_cast<UsingDirectiveDecl>(this))
- return UD->getNominatedNamespace()->getOriginalNamespace() ==
- cast<UsingDirectiveDecl>(OldD)->getNominatedNamespace()
- ->getOriginalNamespace();
-
if (isRedeclarable(getKind())) {
if (getCanonicalDecl() != OldD->getCanonicalDecl())
return false;
@@ -1754,11 +1765,9 @@ SourceLocation DeclaratorDecl::getOuterLocStart() const {
return getTemplateOrInnerLocStart(this);
}
-namespace {
-
// Helper function: returns true if QT is or contains a type
// having a postfix component.
-bool typeIsPostfix(clang::QualType QT) {
+static bool typeIsPostfix(QualType QT) {
while (true) {
const Type* T = QT.getTypePtr();
switch (T->getTypeClass()) {
@@ -1792,8 +1801,6 @@ bool typeIsPostfix(clang::QualType QT) {
}
}
-} // namespace
-
SourceRange DeclaratorDecl::getSourceRange() const {
SourceLocation RangeEnd = getLocation();
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
@@ -1843,7 +1850,7 @@ VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass SC)
: DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
- redeclarable_base(C), Init() {
+ redeclarable_base(C) {
static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
"VarDeclBitfields too large!");
static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
@@ -1967,6 +1974,9 @@ VarDecl *VarDecl::getCanonicalDecl() { return getFirstDecl(); }
VarDecl::DefinitionKind
VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
+ if (isThisDeclarationADemotedDefinition())
+ return DeclarationOnly;
+
// C++ [basic.def]p2:
// A declaration is a definition unless [...] it contains the 'extern'
// specifier or a linkage-specification and neither an initializer [...],
@@ -1980,9 +1990,6 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
//
// FIXME: How do you declare (but not define) a partial specialization of
// a static data member template outside the containing class?
- if (isThisDeclarationADemotedDefinition())
- return DeclarationOnly;
-
if (isStaticDataMember()) {
if (isOutOfLine() &&
!(getCanonicalDecl()->isInline() &&
@@ -2022,9 +2029,12 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
// A variable template specialization (other than a static data member
// template or an explicit specialization) is a declaration until we
// instantiate its initializer.
- if (isa<VarTemplateSpecializationDecl>(this) &&
- getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
- return DeclarationOnly;
+ if (auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(this)) {
+ if (VTSD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization &&
+ !isa<VarTemplatePartialSpecializationDecl>(VTSD) &&
+ !VTSD->IsCompleteDefinition)
+ return DeclarationOnly;
+ }
if (hasExternalStorage())
return DeclarationOnly;
@@ -2408,15 +2418,21 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
dyn_cast<VarTemplateSpecializationDecl>(this)) {
Spec->setSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
- Spec->getPointOfInstantiation().isInvalid())
+ Spec->getPointOfInstantiation().isInvalid()) {
Spec->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
}
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
MSI->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
- MSI->getPointOfInstantiation().isInvalid())
+ MSI->getPointOfInstantiation().isInvalid()) {
MSI->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
}
}
@@ -2548,8 +2564,7 @@ void FunctionDecl::getNameForDiagnostic(
NamedDecl::getNameForDiagnostic(OS, Policy, Qualified);
const TemplateArgumentList *TemplateArgs = getTemplateSpecializationArgs();
if (TemplateArgs)
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs->asArray(), Policy);
+ printTemplateArgumentList(OS, TemplateArgs->asArray(), Policy);
}
bool FunctionDecl::isVariadic() const {
@@ -2747,6 +2762,20 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction(bool *IsAligned) const
return Params == FPT->getNumParams();
}
+bool FunctionDecl::isDestroyingOperatorDelete() const {
+ // C++ P0722:
+ // Within a class C, a single object deallocation function with signature
+ // (T, std::destroying_delete_t, <more params>)
+ // is a destroying operator delete.
+ if (!isa<CXXMethodDecl>(this) || getOverloadedOperator() != OO_Delete ||
+ getNumParams() < 2)
+ return false;
+
+ auto *RD = getParamDecl(1)->getType()->getAsCXXRecordDecl();
+ return RD && RD->isInStdNamespace() && RD->getIdentifier() &&
+ RD->getIdentifier()->isStr("destroying_delete_t");
+}
+
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
return getDeclLanguageLinkage(*this);
}
@@ -2871,7 +2900,6 @@ unsigned FunctionDecl::getBuiltinID() const {
return BuiltinID;
}
-
/// getNumParams - Return the number of parameters this function must have
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
@@ -3057,7 +3085,8 @@ SourceRange FunctionDecl::getExceptionSpecSourceRange() const {
const Attr *FunctionDecl::getUnusedResultAttr() const {
QualType RetType = getReturnType();
if (RetType->isRecordType()) {
- if (const CXXRecordDecl *Ret = RetType->getAsCXXRecordDecl()) {
+ if (const auto *Ret =
+ dyn_cast_or_null<RecordDecl>(RetType->getAsTagDecl())) {
if (const auto *R = Ret->getAttr<WarnUnusedResultAttr>())
return R;
}
@@ -3382,7 +3411,6 @@ DependentFunctionTemplateSpecializationInfo::
DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
const TemplateArgumentListInfo &TArgs)
: AngleLocs(TArgs.getLAngleLoc(), TArgs.getRAngleLoc()) {
-
NumTemplates = Ts.size();
NumArgs = TArgs.size();
@@ -3420,15 +3448,21 @@ FunctionDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
FTSInfo->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization &&
PointOfInstantiation.isValid() &&
- FTSInfo->getPointOfInstantiation().isInvalid())
+ FTSInfo->getPointOfInstantiation().isInvalid()) {
FTSInfo->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
} else if (MemberSpecializationInfo *MSInfo
= TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>()) {
MSInfo->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization &&
PointOfInstantiation.isValid() &&
- MSInfo->getPointOfInstantiation().isInvalid())
+ MSInfo->getPointOfInstantiation().isInvalid()) {
MSInfo->setPointOfInstantiation(PointOfInstantiation);
+ if (ASTMutationListener *L = getASTContext().getASTMutationListener())
+ L->InstantiationRequested(this);
+ }
} else
llvm_unreachable("Function cannot have a template specialization kind");
}
@@ -3598,8 +3632,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
unsigned FieldDecl::getBitWidthValue(const ASTContext &Ctx) const {
assert(isBitField() && "not a bitfield");
- auto *BitWidth = static_cast<Expr *>(InitStorage.getPointer());
- return BitWidth->EvaluateKnownConstInt(Ctx).getZExtValue();
+ return getBitWidth()->EvaluateKnownConstInt(Ctx).getZExtValue();
}
unsigned FieldDecl::getFieldIndex() const {
@@ -3610,7 +3643,8 @@ unsigned FieldDecl::getFieldIndex() const {
if (CachedFieldIndex) return CachedFieldIndex - 1;
unsigned Index = 0;
- const RecordDecl *RD = getParent();
+ const RecordDecl *RD = getParent()->getDefinition();
+ assert(RD && "requested index for field of struct with no definition");
for (auto *Field : RD->fields()) {
Field->getCanonicalDecl()->CachedFieldIndex = Index + 1;
@@ -3622,25 +3656,18 @@ unsigned FieldDecl::getFieldIndex() const {
}
SourceRange FieldDecl::getSourceRange() const {
- switch (InitStorage.getInt()) {
- // All three of these cases store an optional Expr*.
- case ISK_BitWidthOrNothing:
- case ISK_InClassCopyInit:
- case ISK_InClassListInit:
- if (const auto *E = static_cast<const Expr *>(InitStorage.getPointer()))
- return SourceRange(getInnerLocStart(), E->getLocEnd());
- // FALLTHROUGH
-
- case ISK_CapturedVLAType:
- return DeclaratorDecl::getSourceRange();
- }
- llvm_unreachable("bad init storage kind");
+ const Expr *FinalExpr = getInClassInitializer();
+ if (!FinalExpr)
+ FinalExpr = getBitWidth();
+ if (FinalExpr)
+ return SourceRange(getInnerLocStart(), FinalExpr->getLocEnd());
+ return DeclaratorDecl::getSourceRange();
}
void FieldDecl::setCapturedVLAType(const VariableArrayType *VLAType) {
assert((getParent()->isLambda() || getParent()->isCapturedRecord()) &&
"capturing type in non-lambda or captured record.");
- assert(InitStorage.getInt() == ISK_BitWidthOrNothing &&
+ assert(InitStorage.getInt() == ISK_NoInit &&
InitStorage.getPointer() == nullptr &&
"bit width, initializer or captured type already set");
InitStorage.setPointerAndInt(const_cast<VariableArrayType *>(VLAType),
@@ -3753,7 +3780,7 @@ void TagDecl::setTemplateParameterListsInfo(
// EnumDecl Implementation
//===----------------------------------------------------------------------===//
-void EnumDecl::anchor() { }
+void EnumDecl::anchor() {}
EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -3862,12 +3889,10 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
RecordDecl *PrevDecl)
- : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
- HasFlexibleArrayMember = false;
- AnonymousStructOrUnion = false;
- HasObjectMember = false;
- HasVolatileMember = false;
- LoadedFieldsFromExternalStorage = false;
+ : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+ HasFlexibleArrayMember(false), AnonymousStructOrUnion(false),
+ HasObjectMember(false), HasVolatileMember(false),
+ LoadedFieldsFromExternalStorage(false) {
assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
}
@@ -3958,9 +3983,9 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().Sanitize.hasOneOf(
- SanitizerKind::Address | SanitizerKind::KernelAddress) ||
- !Context.getLangOpts().SanitizeAddressFieldPadding)
+ const SanitizerMask EnabledAsanMask = Context.getLangOpts().Sanitize.Mask &
+ (SanitizerKind::Address | SanitizerKind::KernelAddress);
+ if (!EnabledAsanMask || !Context.getLangOpts().SanitizeAddressFieldPadding)
return false;
const auto &Blacklist = Context.getSanitizerBlacklist();
const auto *CXXRD = dyn_cast<CXXRecordDecl>(this);
@@ -3978,9 +4003,11 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ReasonToReject = 4; // has trivial destructor.
else if (CXXRD->isStandardLayout())
ReasonToReject = 5; // is standard layout.
- else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding"))
+ else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(),
+ "field-padding"))
ReasonToReject = 6; // is in a blacklisted file.
- else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(),
+ else if (Blacklist.isBlacklistedType(EnabledAsanMask,
+ getQualifiedNameAsString(),
"field-padding"))
ReasonToReject = 7; // is blacklisted.
@@ -4014,7 +4041,6 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
return nullptr;
}
-
//===----------------------------------------------------------------------===//
// BlockDecl Implementation
//===----------------------------------------------------------------------===//
@@ -4060,13 +4086,13 @@ SourceRange BlockDecl::getSourceRange() const {
// Other Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
-void TranslationUnitDecl::anchor() { }
+void TranslationUnitDecl::anchor() {}
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
}
-void PragmaCommentDecl::anchor() { }
+void PragmaCommentDecl::anchor() {}
PragmaCommentDecl *PragmaCommentDecl::Create(const ASTContext &C,
TranslationUnitDecl *DC,
@@ -4088,7 +4114,7 @@ PragmaCommentDecl *PragmaCommentDecl::CreateDeserialized(ASTContext &C,
PragmaCommentDecl(nullptr, SourceLocation(), PCK_Unknown);
}
-void PragmaDetectMismatchDecl::anchor() { }
+void PragmaDetectMismatchDecl::anchor() {}
PragmaDetectMismatchDecl *
PragmaDetectMismatchDecl::Create(const ASTContext &C, TranslationUnitDecl *DC,
@@ -4113,14 +4139,14 @@ PragmaDetectMismatchDecl::CreateDeserialized(ASTContext &C, unsigned ID,
PragmaDetectMismatchDecl(nullptr, SourceLocation(), 0);
}
-void ExternCContextDecl::anchor() { }
+void ExternCContextDecl::anchor() {}
ExternCContextDecl *ExternCContextDecl::Create(const ASTContext &C,
TranslationUnitDecl *DC) {
return new (C, DC) ExternCContextDecl(DC);
}
-void LabelDecl::anchor() { }
+void LabelDecl::anchor() {}
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II) {
@@ -4146,7 +4172,7 @@ void LabelDecl::setMSAsmLabel(StringRef Name) {
MSAsmName = Buffer;
}
-void ValueDecl::anchor() { }
+void ValueDecl::anchor() {}
bool ValueDecl::isWeak() const {
for (const auto *I : attrs())
@@ -4156,7 +4182,7 @@ bool ValueDecl::isWeak() const {
return isWeakImported();
}
-void ImplicitParamDecl::anchor() { }
+void ImplicitParamDecl::anchor() {}
ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc,
@@ -4239,7 +4265,7 @@ EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
QualType(), nullptr, llvm::APSInt());
}
-void IndirectFieldDecl::anchor() { }
+void IndirectFieldDecl::anchor() {}
IndirectFieldDecl::IndirectFieldDecl(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName N,
@@ -4273,7 +4299,7 @@ SourceRange EnumConstantDecl::getSourceRange() const {
return SourceRange(getLocation(), End);
}
-void TypeDecl::anchor() { }
+void TypeDecl::anchor() {}
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
@@ -4281,7 +4307,7 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
-void TypedefNameDecl::anchor() { }
+void TypedefNameDecl::anchor() {}
TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) {
@@ -4355,7 +4381,7 @@ SourceRange TypeAliasDecl::getSourceRange() const {
return SourceRange(getLocStart(), RangeEnd);
}
-void FileScopeAsmDecl::anchor() { }
+void FileScopeAsmDecl::anchor() {}
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
StringLiteral *Str,
@@ -4398,9 +4424,7 @@ static unsigned getNumModuleIdentifiers(Module *Mod) {
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true),
- NextLocalImport()
-{
+ : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, true) {
assert(getNumModuleIdentifiers(Imported) == IdentifierLocs.size());
auto *StoredLocs = getTrailingObjects<SourceLocation>();
std::uninitialized_copy(IdentifierLocs.begin(), IdentifierLocs.end(),
@@ -4409,9 +4433,7 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
Module *Imported, SourceLocation EndLoc)
- : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false),
- NextLocalImport()
-{
+ : Decl(Import, DC, StartLoc), ImportedAndComplete(Imported, false) {
*getTrailingObjects<SourceLocation>() = EndLoc;
}
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index cd2c83a02f59..29ce7ae034b5 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1,4 +1,4 @@
-//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
+//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,6 +15,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/AttrIterator.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclContextInternals.h"
@@ -25,11 +26,30 @@
#include "clang/AST/DependentDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/Stmt.h"
-#include "clang/AST/StmtCXX.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <tuple>
+#include <utility>
+
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -74,8 +94,9 @@ void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
DeclContext *Parent, std::size_t Extra) {
assert(!Parent || &Parent->getParentASTContext() == &Ctx);
// With local visibility enabled, we track the owning module even for local
- // declarations.
- if (Ctx.getLangOpts().trackLocalOwningModule()) {
+ // declarations. We create the TU decl early and may not yet know what the
+ // LangOpts are, so conservatively allocate the storage.
+ if (Ctx.getLangOpts().trackLocalOwningModule() || !Parent) {
// Ensure required alignment of the resulting object by adding extra
// padding at the start if required.
size_t ExtraAlign =
@@ -229,7 +250,6 @@ const DeclContext *Decl::getParentFunctionOrMethod() const {
return nullptr;
}
-
//===----------------------------------------------------------------------===//
// PrettyStackTraceDecl Implementation
//===----------------------------------------------------------------------===//
@@ -259,7 +279,7 @@ void PrettyStackTraceDecl::print(raw_ostream &OS) const {
//===----------------------------------------------------------------------===//
// Out-of-line virtual method providing a home for Decl.
-Decl::~Decl() { }
+Decl::~Decl() = default;
void Decl::setDeclContext(DeclContext *DC) {
DeclCtx = DC;
@@ -314,12 +334,11 @@ bool Decl::isLexicallyWithinFunctionOrMethod() const {
}
bool Decl::isInAnonymousNamespace() const {
- const DeclContext *DC = getDeclContext();
- do {
+ for (const DeclContext *DC = getDeclContext(); DC; DC = DC->getParent()) {
if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC))
if (ND->isAnonymousNamespace())
return true;
- } while ((DC = DC->getParent()));
+ }
return false;
}
@@ -680,7 +699,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case CXXConversion:
case EnumConstant:
case Var:
- case Binding:
case ImplicitParam:
case ParmVar:
case ObjCMethod:
@@ -692,10 +710,11 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case IndirectField:
return IDNS_Ordinary | IDNS_Member;
+ case Binding:
case NonTypeTemplateParm:
- // Non-type template parameters are not found by lookups that ignore
- // non-types, but they are found by redeclaration lookups for tag types,
- // so we include them in the tag namespace.
+ case VarTemplate:
+ // These (C++-only) declarations are found by redeclaration lookup for
+ // tag types, so we include them in the tag namespace.
return IDNS_Ordinary | IDNS_Tag;
case ObjCCompatibleAlias:
@@ -704,7 +723,6 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case Typedef:
case TypeAlias:
- case TypeAliasTemplate:
case TemplateTypeParm:
case ObjCTypeParam:
return IDNS_Ordinary | IDNS_Type;
@@ -740,11 +758,11 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
return IDNS_Namespace;
case FunctionTemplate:
- case VarTemplate:
return IDNS_Ordinary;
case ClassTemplate:
case TemplateTemplateParm:
+ case TypeAliasTemplate:
return IDNS_Ordinary | IDNS_Tag | IDNS_Type;
case OMPDeclareReduction:
@@ -914,7 +932,6 @@ const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
return Ty->getAs<FunctionType>();
}
-
/// Starting at a given context (a Decl or DeclContext), look for a
/// code context that is not a closure (a lambda, block, etc.).
template <class T> static Decl *getNonClosureContext(T *D) {
@@ -967,7 +984,7 @@ bool DeclContext::classof(const Decl *D) {
}
}
-DeclContext::~DeclContext() { }
+DeclContext::~DeclContext() = default;
/// \brief Find the parent context of this context that will be
/// used for unqualified name lookup.
@@ -1058,15 +1075,14 @@ static bool isLinkageSpecContext(const DeclContext *DC,
}
bool DeclContext::isExternCContext() const {
- return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_c);
+ return isLinkageSpecContext(this, LinkageSpecDecl::lang_c);
}
const LinkageSpecDecl *DeclContext::getExternCContext() const {
const DeclContext *DC = this;
while (DC->getDeclKind() != Decl::TranslationUnit) {
if (DC->getDeclKind() == Decl::LinkageSpec &&
- cast<LinkageSpecDecl>(DC)->getLanguage() ==
- clang::LinkageSpecDecl::lang_c)
+ cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecDecl::lang_c)
return cast<LinkageSpecDecl>(DC);
DC = DC->getLexicalParent();
}
@@ -1074,7 +1090,7 @@ const LinkageSpecDecl *DeclContext::getExternCContext() const {
}
bool DeclContext::isExternCXXContext() const {
- return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_cxx);
+ return isLinkageSpecContext(this, LinkageSpecDecl::lang_cxx);
}
bool DeclContext::Encloses(const DeclContext *DC) const {
@@ -1109,13 +1125,11 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::ObjCInterface:
if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(this)->getDefinition())
return Def;
-
return this;
case Decl::ObjCProtocol:
if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(this)->getDefinition())
return Def;
-
return this;
case Decl::ObjCCategory:
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 5782b7b56c96..41f2449a9d6a 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1,4 +1,4 @@
-//===--- DeclCXX.cpp - C++ Declaration AST Node Implementation ------------===//
+//===- DeclCXX.cpp - C++ Declaration AST Node Implementation --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,26 +10,51 @@
// This file implements the C++ related Decl classes.
//
//===----------------------------------------------------------------------===//
+
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
+#include "clang/AST/ASTUnresolvedSet.h"
#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/LambdaCapture.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ODRHash.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/STLExtras.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
using namespace clang;
//===----------------------------------------------------------------------===//
// Decl Allocation/Deallocation Method Implementations
//===----------------------------------------------------------------------===//
-void AccessSpecDecl::anchor() { }
+void AccessSpecDecl::anchor() {}
AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) AccessSpecDecl(EmptyShell());
@@ -76,9 +101,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false), IsLambda(false),
- IsParsingBaseSpecifiers(false), HasODRHash(false), ODRHash(0),
- NumBases(0), NumVBases(0), Bases(), VBases(), Definition(D),
- FirstFriend() {}
+ IsParsingBaseSpecifiers(false), HasODRHash(false), Definition(D) {}
CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getBasesSlowCase() const {
return Bases.get(Definition->getASTContext().getExternalSource());
@@ -94,13 +117,12 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
CXXRecordDecl *PrevDecl)
: RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
DefinitionData(PrevDecl ? PrevDecl->DefinitionData
- : nullptr),
- TemplateOrInstantiation() {}
+ : nullptr) {}
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
- CXXRecordDecl* PrevDecl,
+ CXXRecordDecl *PrevDecl,
bool DelayTypeCreation) {
CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
IdLoc, Id, PrevDecl);
@@ -148,7 +170,7 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
C.Deallocate(data().getBases());
if (NumBases) {
- if (!C.getLangOpts().CPlusPlus1z) {
+ if (!C.getLangOpts().CPlusPlus17) {
// C++ [dcl.init.aggr]p1:
// An aggregate is [...] a class with [...] no base classes [...].
data().Aggregate = false;
@@ -403,7 +425,6 @@ unsigned CXXRecordDecl::getODRHash() const {
return DefinitionData->ODRHash;
}
-
void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
// C++11 [class.copy]p11:
// A defaulted copy/move constructor for a class X is defined as
@@ -1470,6 +1491,66 @@ bool CXXRecordDecl::isAnyDestructorNoReturn() const {
return false;
}
+static bool isDeclContextInNamespace(const DeclContext *DC) {
+ while (!DC->isTranslationUnit()) {
+ if (DC->isNamespace())
+ return true;
+ DC = DC->getParent();
+ }
+ return false;
+}
+
+bool CXXRecordDecl::isInterfaceLike() const {
+ assert(hasDefinition() && "checking for interface-like without a definition");
+ // All __interfaces are inheritently interface-like.
+ if (isInterface())
+ return true;
+
+ // Interface-like types cannot have a user declared constructor, destructor,
+ // friends, VBases, conversion functions, or fields. Additionally, lambdas
+ // cannot be interface types.
+ if (isLambda() || hasUserDeclaredConstructor() ||
+ hasUserDeclaredDestructor() || !field_empty() || hasFriends() ||
+ getNumVBases() > 0 || conversion_end() - conversion_begin() > 0)
+ return false;
+
+ // No interface-like type can have a method with a definition.
+ for (const auto *const Method : methods())
+ if (Method->isDefined() && !Method->isImplicit())
+ return false;
+
+ // Check "Special" types.
+ const auto *Uuid = getAttr<UuidAttr>();
+ // MS SDK declares IUnknown/IDispatch both in the root of a TU, or in an
+ // extern C++ block directly in the TU. These are only valid if in one
+ // of these two situations.
+ if (Uuid && isStruct() && !getDeclContext()->isExternCContext() &&
+ !isDeclContextInNamespace(getDeclContext()) &&
+ ((getName() == "IUnknown" &&
+ Uuid->getGuid() == "00000000-0000-0000-C000-000000000046") ||
+ (getName() == "IDispatch" &&
+ Uuid->getGuid() == "00020400-0000-0000-C000-000000000046"))) {
+ if (getNumBases() > 0)
+ return false;
+ return true;
+ }
+
+ // FIXME: Any access specifiers is supposed to make this no longer interface
+ // like.
+
+ // If this isn't a 'special' type, it must have a single interface-like base.
+ if (getNumBases() != 1)
+ return false;
+
+ const auto BaseSpec = *bases_begin();
+ if (BaseSpec.isVirtual() || BaseSpec.getAccessSpecifier() != AS_public)
+ return false;
+ const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();
+ if (Base->isInterface() || !Base->isInterfaceLike())
+ return false;
+ return true;
+}
+
void CXXRecordDecl::completeDefinition() {
completeDefinition(nullptr);
}
@@ -1530,7 +1611,7 @@ bool CXXRecordDecl::mayBeAbstract() const {
return false;
}
-void CXXDeductionGuideDecl::anchor() { }
+void CXXDeductionGuideDecl::anchor() {}
CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit,
@@ -1547,7 +1628,7 @@ CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C,
nullptr, SourceLocation());
}
-void CXXMethodDecl::anchor() { }
+void CXXMethodDecl::anchor() {}
bool CXXMethodDecl::isStatic() const {
const CXXMethodDecl *MD = getCanonicalDecl();
@@ -1561,9 +1642,7 @@ bool CXXMethodDecl::isStatic() const {
static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
const CXXMethodDecl *BaseMD) {
- for (CXXMethodDecl::method_iterator I = DerivedMD->begin_overridden_methods(),
- E = DerivedMD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *MD = *I;
+ for (const CXXMethodDecl *MD : DerivedMD->overridden_methods()) {
if (MD->getCanonicalDecl() == BaseMD->getCanonicalDecl())
return true;
if (recursivelyOverrides(MD, BaseMD))
@@ -1728,6 +1807,14 @@ bool CXXMethodDecl::isUsualDeallocationFunction() const {
return true;
unsigned UsualParams = 1;
+ // C++ P0722:
+ // A destroying operator delete is a usual deallocation function if
+ // removing the std::destroying_delete_t parameter and changing the
+ // first parameter type from T* to void* results in the signature of
+ // a usual deallocation function.
+ if (isDestroyingOperatorDelete())
+ ++UsualParams;
+
// C++ <=14 [basic.stc.dynamic.deallocation]p2:
// [...] If class T does not declare such an operator delete but does
// declare a member deallocation function named operator delete with
@@ -1886,43 +1973,34 @@ CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
SourceLocation L, Expr *Init,
SourceLocation R,
SourceLocation EllipsisLoc)
- : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init),
- LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual),
- IsWritten(false), SourceOrder(0)
-{
-}
+ : Initializee(TInfo), MemberOrEllipsisLocation(EllipsisLoc), Init(Init),
+ LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(IsVirtual),
+ IsWritten(false), SourceOrder(0) {}
CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
FieldDecl *Member,
SourceLocation MemberLoc,
SourceLocation L, Expr *Init,
SourceLocation R)
- : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
- LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
- IsWritten(false), SourceOrder(0)
-{
-}
+ : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
+ LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
+ IsWritten(false), SourceOrder(0) {}
CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
IndirectFieldDecl *Member,
SourceLocation MemberLoc,
SourceLocation L, Expr *Init,
SourceLocation R)
- : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
- LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
- IsWritten(false), SourceOrder(0)
-{
-}
+ : Initializee(Member), MemberOrEllipsisLocation(MemberLoc), Init(Init),
+ LParenLoc(L), RParenLoc(R), IsDelegating(false), IsVirtual(false),
+ IsWritten(false), SourceOrder(0) {}
CXXCtorInitializer::CXXCtorInitializer(ASTContext &Context,
TypeSourceInfo *TInfo,
SourceLocation L, Expr *Init,
SourceLocation R)
- : Initializee(TInfo), MemberOrEllipsisLocation(), Init(Init),
- LParenLoc(L), RParenLoc(R), IsDelegating(true), IsVirtual(false),
- IsWritten(false), SourceOrder(0)
-{
-}
+ : Initializee(TInfo), Init(Init), LParenLoc(L), RParenLoc(R),
+ IsDelegating(true), IsVirtual(false), IsWritten(false), SourceOrder(0) {}
TypeLoc CXXCtorInitializer::getBaseClassLoc() const {
if (isBaseInitializer())
@@ -1962,7 +2040,7 @@ SourceRange CXXCtorInitializer::getSourceRange() const {
return SourceRange(getSourceLocation(), getRParenLoc());
}
-void CXXConstructorDecl::anchor() { }
+void CXXConstructorDecl::anchor() {}
CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
unsigned ID,
@@ -2105,7 +2183,7 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const {
return true;
}
-void CXXDestructorDecl::anchor() { }
+void CXXDestructorDecl::anchor() {}
CXXDestructorDecl *
CXXDestructorDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
@@ -2127,16 +2205,17 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
isInline, isImplicitlyDeclared);
}
-void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD) {
+void CXXDestructorDecl::setOperatorDelete(FunctionDecl *OD, Expr *ThisArg) {
auto *First = cast<CXXDestructorDecl>(getFirstDecl());
if (OD && !First->OperatorDelete) {
First->OperatorDelete = OD;
+ First->OperatorDeleteThisArg = ThisArg;
if (auto *L = getASTMutationListener())
- L->ResolvedOperatorDelete(First, OD);
+ L->ResolvedOperatorDelete(First, OD, ThisArg);
}
}
-void CXXConversionDecl::anchor() { }
+void CXXConversionDecl::anchor() {}
CXXConversionDecl *
CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
@@ -2166,7 +2245,7 @@ bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
getConversionType()->isBlockPointerType();
}
-void LinkageSpecDecl::anchor() { }
+void LinkageSpecDecl::anchor() {}
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
DeclContext *DC,
@@ -2183,7 +2262,7 @@ LinkageSpecDecl *LinkageSpecDecl::CreateDeserialized(ASTContext &C,
SourceLocation(), lang_c, false);
}
-void UsingDirectiveDecl::anchor() { }
+void UsingDirectiveDecl::anchor() {}
UsingDirectiveDecl *UsingDirectiveDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -2217,7 +2296,7 @@ NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, NamespaceDecl *PrevDecl)
: NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
- redeclarable_base(C), LocStart(StartLoc), RBraceLoc(),
+ redeclarable_base(C), LocStart(StartLoc),
AnonOrFirstNamespaceAndInline(nullptr, Inline) {
setPreviousDecl(PrevDecl);
@@ -2257,21 +2336,25 @@ bool NamespaceDecl::isOriginalNamespace() const { return isFirstDecl(); }
NamespaceDecl *NamespaceDecl::getNextRedeclarationImpl() {
return getNextRedeclaration();
}
+
NamespaceDecl *NamespaceDecl::getPreviousDeclImpl() {
return getPreviousDecl();
}
+
NamespaceDecl *NamespaceDecl::getMostRecentDeclImpl() {
return getMostRecentDecl();
}
-void NamespaceAliasDecl::anchor() { }
+void NamespaceAliasDecl::anchor() {}
NamespaceAliasDecl *NamespaceAliasDecl::getNextRedeclarationImpl() {
return getNextRedeclaration();
}
+
NamespaceAliasDecl *NamespaceAliasDecl::getPreviousDeclImpl() {
return getPreviousDecl();
}
+
NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
return getMostRecentDecl();
}
@@ -2298,7 +2381,7 @@ NamespaceAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
SourceLocation(), nullptr);
}
-void UsingShadowDecl::anchor() { }
+void UsingShadowDecl::anchor() {}
UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
@@ -2313,7 +2396,7 @@ UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC,
UsingShadowDecl::UsingShadowDecl(Kind K, ASTContext &C, EmptyShell Empty)
: NamedDecl(K, nullptr, SourceLocation(), DeclarationName()),
- redeclarable_base(C), Underlying(), UsingOrNextShadow() {}
+ redeclarable_base(C) {}
UsingShadowDecl *
UsingShadowDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
@@ -2328,7 +2411,7 @@ UsingDecl *UsingShadowDecl::getUsingDecl() const {
return cast<UsingDecl>(Shadow->UsingOrNextShadow);
}
-void ConstructorUsingShadowDecl::anchor() { }
+void ConstructorUsingShadowDecl::anchor() {}
ConstructorUsingShadowDecl *
ConstructorUsingShadowDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2347,7 +2430,7 @@ CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const {
return getUsingDecl()->getQualifier()->getAsRecordDecl();
}
-void UsingDecl::anchor() { }
+void UsingDecl::anchor() {}
void UsingDecl::addShadowDecl(UsingShadowDecl *S) {
assert(std::find(shadow_begin(), shadow_end(), S) == shadow_end() &&
@@ -2399,7 +2482,7 @@ SourceRange UsingDecl::getSourceRange() const {
return SourceRange(Begin, getNameInfo().getEndLoc());
}
-void UsingPackDecl::anchor() { }
+void UsingPackDecl::anchor() {}
UsingPackDecl *UsingPackDecl::Create(ASTContext &C, DeclContext *DC,
NamedDecl *InstantiatedFrom,
@@ -2419,7 +2502,7 @@ UsingPackDecl *UsingPackDecl::CreateDeserialized(ASTContext &C, unsigned ID,
return Result;
}
-void UnresolvedUsingValueDecl::anchor() { }
+void UnresolvedUsingValueDecl::anchor() {}
UnresolvedUsingValueDecl *
UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2447,7 +2530,7 @@ SourceRange UnresolvedUsingValueDecl::getSourceRange() const {
return SourceRange(Begin, getNameInfo().getEndLoc());
}
-void UnresolvedUsingTypenameDecl::anchor() { }
+void UnresolvedUsingTypenameDecl::anchor() {}
UnresolvedUsingTypenameDecl *
UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2469,7 +2552,7 @@ UnresolvedUsingTypenameDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
SourceLocation(), nullptr, SourceLocation());
}
-void StaticAssertDecl::anchor() { }
+void StaticAssertDecl::anchor() {}
StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StaticAssertLoc,
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index 121403b07e57..461bf36858b7 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -1,4 +1,4 @@
-//===--- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation --===//
+//===- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation ----===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,12 +12,20 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclFriend.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstddef>
+
using namespace clang;
-void FriendDecl::anchor() { }
+void FriendDecl::anchor() {}
FriendDecl *FriendDecl::getNextFriendSlowCase() {
return cast_or_null<FriendDecl>(
@@ -28,9 +36,9 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
FriendUnion Friend,
SourceLocation FriendL,
- ArrayRef<TemplateParameterList*> FriendTypeTPLists) {
+ ArrayRef<TemplateParameterList *> FriendTypeTPLists) {
#ifndef NDEBUG
- if (Friend.is<NamedDecl*>()) {
+ if (Friend.is<NamedDecl *>()) {
NamedDecl *D = Friend.get<NamedDecl*>();
assert(isa<FunctionDecl>(D) ||
isa<CXXRecordDecl>(D) ||
@@ -42,7 +50,7 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
assert(D->getFriendObjectKind() ||
(cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind()));
// These template parameters are for friend types only.
- assert(FriendTypeTPLists.size() == 0);
+ assert(FriendTypeTPLists.empty());
}
#endif
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index 2f95e1f1c345..f74ef9bbb839 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -1,4 +1,4 @@
-//===--- DeclGroup.cpp - Classes for representing groups of Decls -*- C++ -*-==//
+//===- DeclGroup.cpp - Classes for representing groups of Decls -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,7 +13,9 @@
#include "clang/AST/DeclGroup.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/Decl.h"
+#include <cassert>
+#include <memory>
+
using namespace clang;
DeclGroup* DeclGroup::Create(ASTContext &C, Decl **Decls, unsigned NumDecls) {
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index d8bdb6369e94..f95d5def47ac 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1,4 +1,4 @@
-//===--- DeclObjC.cpp - ObjC Declaration AST Node Implementation ----------===//
+//===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,9 +15,27 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/Stmt.h"
-#include "llvm/ADT/STLExtras.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <utility>
+
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -28,7 +46,6 @@ void ObjCListBase::set(void *const* InList, unsigned Elts, ASTContext &Ctx) {
List = nullptr;
if (Elts == 0) return; // Setting to an empty list is a noop.
-
List = new (Ctx) void*[Elts];
NumElts = Elts;
memcpy(List, InList, sizeof(void*)*Elts);
@@ -48,7 +65,7 @@ void ObjCProtocolList::set(ObjCProtocolDecl* const* InList, unsigned Elts,
// ObjCInterfaceDecl
//===----------------------------------------------------------------------===//
-void ObjCContainerDecl::anchor() { }
+void ObjCContainerDecl::anchor() {}
/// getIvarDecl - This method looks up an ivar in this ContextDecl.
///
@@ -82,7 +99,6 @@ ObjCContainerDecl::getMethod(Selector Sel, bool isInstance,
// - (int) class_method;
// + (float) class_method;
// @end
- //
lookup_result R = lookup(Sel);
for (lookup_iterator Meth = R.begin(), MethEnd = R.end();
Meth != MethEnd; ++Meth) {
@@ -280,7 +296,7 @@ ObjCPropertyDecl *ObjCContainerDecl::FindPropertyDeclaration(
return nullptr;
}
-void ObjCInterfaceDecl::anchor() { }
+void ObjCInterfaceDecl::anchor() {}
ObjCTypeParamList *ObjCInterfaceDecl::getTypeParamList() const {
// If this particular declaration has a type parameter list, return it.
@@ -341,7 +357,6 @@ SourceLocation ObjCInterfaceDecl::getSuperClassLoc() const {
/// FindPropertyVisibleInPrimaryClass - Finds declaration of the property
/// with name 'PropertyId' in the primary class; including those in protocols
/// (direct or indirect) used by the primary class.
-///
ObjCPropertyDecl *
ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass(
IdentifierInfo *PropertyId,
@@ -409,8 +424,7 @@ const ObjCInterfaceDecl *ObjCInterfaceDecl::isObjCRequiresPropertyDefs() const {
void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
ObjCProtocolDecl *const* ExtList, unsigned ExtNum,
- ASTContext &C)
-{
+ ASTContext &C) {
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -488,7 +502,7 @@ bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
return true;
case DefinitionData::IDI_NotInherited:
return false;
- case DefinitionData::IDI_Unknown: {
+ case DefinitionData::IDI_Unknown:
// If the class introduced initializers we conservatively assume that we
// don't know if any of them is a designated initializer to avoid possible
// misleading warnings.
@@ -510,7 +524,6 @@ bool ObjCInterfaceDecl::inheritsDesignatedInitializers() const {
return data().InheritedDesignatedInitializers ==
DefinitionData::IDI_Inherited;
}
- }
llvm_unreachable("unexpected InheritedDesignatedInitializers value");
}
@@ -902,7 +915,6 @@ ObjCMethodDecl *ObjCMethodDecl::getCanonicalDecl() {
if (ObjCMethodDecl *MD = IFD->getMethod(getSelector(),
isInstanceMethod()))
return MD;
-
} else if (ObjCCategoryImplDecl *CImplD =
dyn_cast<ObjCCategoryImplDecl>(CtxD)) {
if (ObjCCategoryDecl *CatD = CImplD->getCategoryDecl())
@@ -1312,7 +1324,8 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
if (!CheckOverrides)
return nullptr;
- typedef SmallVector<const ObjCMethodDecl *, 8> OverridesTy;
+ using OverridesTy = SmallVector<const ObjCMethodDecl *, 8>;
+
OverridesTy Overrides;
getOverriddenMethods(Overrides);
for (OverridesTy::const_iterator I = Overrides.begin(), E = Overrides.end();
@@ -1328,7 +1341,7 @@ ObjCMethodDecl::findPropertyDecl(bool CheckOverrides) const {
// ObjCTypeParamDecl
//===----------------------------------------------------------------------===//
-void ObjCTypeParamDecl::anchor() { }
+void ObjCTypeParamDecl::anchor() {}
ObjCTypeParamDecl *ObjCTypeParamDecl::Create(ASTContext &ctx, DeclContext *dc,
ObjCTypeParamVariance variance,
@@ -1373,14 +1386,12 @@ SourceRange ObjCTypeParamDecl::getSourceRange() const {
ObjCTypeParamList::ObjCTypeParamList(SourceLocation lAngleLoc,
ArrayRef<ObjCTypeParamDecl *> typeParams,
SourceLocation rAngleLoc)
- : NumParams(typeParams.size())
-{
+ : NumParams(typeParams.size()) {
Brackets.Begin = lAngleLoc.getRawEncoding();
Brackets.End = rAngleLoc.getRawEncoding();
std::copy(typeParams.begin(), typeParams.end(), begin());
}
-
ObjCTypeParamList *ObjCTypeParamList::create(
ASTContext &ctx,
SourceLocation lAngleLoc,
@@ -1438,8 +1449,7 @@ ObjCInterfaceDecl::ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC,
ObjCInterfaceDecl *PrevDecl,
bool IsInternal)
: ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, AtLoc),
- redeclarable_base(C), TypeForDecl(nullptr), TypeParamList(nullptr),
- Data() {
+ redeclarable_base(C) {
setPreviousDecl(PrevDecl);
// Copy the 'data' pointer over.
@@ -1518,19 +1528,22 @@ void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) {
}
namespace {
- struct SynthesizeIvarChunk {
- uint64_t Size;
- ObjCIvarDecl *Ivar;
- SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
+
+struct SynthesizeIvarChunk {
+ uint64_t Size;
+ ObjCIvarDecl *Ivar;
+
+ SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar)
: Size(size), Ivar(ivar) {}
- };
+};
- bool operator<(const SynthesizeIvarChunk & LHS,
- const SynthesizeIvarChunk &RHS) {
- return LHS.Size < RHS.Size;
- }
+bool operator<(const SynthesizeIvarChunk & LHS,
+ const SynthesizeIvarChunk &RHS) {
+ return LHS.Size < RHS.Size;
}
+} // namespace
+
/// all_declared_ivar_begin - return first ivar declared in this class,
/// its extensions and its implementation. Lazily build the list on first
/// access.
@@ -1694,7 +1707,7 @@ bool ObjCInterfaceDecl::ClassImplementsProtocol(ObjCProtocolDecl *lProto,
// ObjCIvarDecl
//===----------------------------------------------------------------------===//
-void ObjCIvarDecl::anchor() { }
+void ObjCIvarDecl::anchor() {}
ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation StartLoc,
@@ -1771,7 +1784,7 @@ QualType ObjCIvarDecl::getUsageType(QualType objectType) const {
// ObjCAtDefsFieldDecl
//===----------------------------------------------------------------------===//
-void ObjCAtDefsFieldDecl::anchor() { }
+void ObjCAtDefsFieldDecl::anchor() {}
ObjCAtDefsFieldDecl
*ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC,
@@ -1791,14 +1804,14 @@ ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::CreateDeserialized(ASTContext &C,
// ObjCProtocolDecl
//===----------------------------------------------------------------------===//
-void ObjCProtocolDecl::anchor() { }
+void ObjCProtocolDecl::anchor() {}
ObjCProtocolDecl::ObjCProtocolDecl(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, SourceLocation nameLoc,
SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl)
: ObjCContainerDecl(ObjCProtocol, DC, Id, nameLoc, atStartLoc),
- redeclarable_base(C), Data() {
+ redeclarable_base(C) {
setPreviousDecl(PrevDecl);
if (PrevDecl)
Data = PrevDecl->Data;
@@ -1874,7 +1887,6 @@ void ObjCProtocolDecl::startDefinition() {
void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
PropertyDeclOrder &PO) const {
-
if (const ObjCProtocolDecl *PDecl = getDefinition()) {
for (auto *Prop : PDecl->properties()) {
// Insert into PM if not there already.
@@ -1921,7 +1933,7 @@ ObjCProtocolDecl::getObjCRuntimeNameAsString() const {
// ObjCCategoryDecl
//===----------------------------------------------------------------------===//
-void ObjCCategoryDecl::anchor() { }
+void ObjCCategoryDecl::anchor() {}
ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
SourceLocation ClassNameLoc,
@@ -1930,11 +1942,9 @@ ObjCCategoryDecl::ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc,
ObjCTypeParamList *typeParamList,
SourceLocation IvarLBraceLoc,
SourceLocation IvarRBraceLoc)
- : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
- ClassInterface(IDecl), TypeParamList(nullptr),
- NextClassCategory(nullptr), CategoryNameLoc(CategoryNameLoc),
- IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc)
-{
+ : ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
+ ClassInterface(IDecl), CategoryNameLoc(CategoryNameLoc),
+ IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
setTypeParamList(typeParamList);
}
@@ -1994,7 +2004,7 @@ void ObjCCategoryDecl::setTypeParamList(ObjCTypeParamList *TPL) {
// ObjCCategoryImplDecl
//===----------------------------------------------------------------------===//
-void ObjCCategoryImplDecl::anchor() { }
+void ObjCCategoryImplDecl::anchor() {}
ObjCCategoryImplDecl *
ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2023,8 +2033,7 @@ ObjCCategoryDecl *ObjCCategoryImplDecl::getCategoryDecl() const {
return nullptr;
}
-
-void ObjCImplDecl::anchor() { }
+void ObjCImplDecl::anchor() {}
void ObjCImplDecl::addPropertyImplementation(ObjCPropertyImplDecl *property) {
// FIXME: The context should be correct before we get here.
@@ -2052,7 +2061,6 @@ void ObjCImplDecl::setClassInterface(ObjCInterfaceDecl *IFace) {
/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of
/// properties implemented in this \@implementation block and returns
/// the implemented property that uses it.
-///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
for (auto *PID : property_impls())
@@ -2065,7 +2073,6 @@ FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const {
/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl
/// added to the list of those properties \@synthesized/\@dynamic in this
/// category \@implementation block.
-///
ObjCPropertyImplDecl *ObjCImplDecl::
FindPropertyImplDecl(IdentifierInfo *Id,
ObjCPropertyQueryKind QueryKind) const {
@@ -2103,7 +2110,7 @@ raw_ostream &clang::operator<<(raw_ostream &OS,
// ObjCImplementationDecl
//===----------------------------------------------------------------------===//
-void ObjCImplementationDecl::anchor() { }
+void ObjCImplementationDecl::anchor() {}
ObjCImplementationDecl *
ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2155,7 +2162,7 @@ raw_ostream &clang::operator<<(raw_ostream &OS,
// ObjCCompatibleAliasDecl
//===----------------------------------------------------------------------===//
-void ObjCCompatibleAliasDecl::anchor() { }
+void ObjCCompatibleAliasDecl::anchor() {}
ObjCCompatibleAliasDecl *
ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
@@ -2175,7 +2182,7 @@ ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
// ObjCPropertyDecl
//===----------------------------------------------------------------------===//
-void ObjCPropertyDecl::anchor() { }
+void ObjCPropertyDecl::anchor() {}
ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 6eeba88e4033..b792c5920a55 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -28,6 +28,7 @@ namespace {
class DeclPrinter : public DeclVisitor<DeclPrinter> {
raw_ostream &Out;
PrintingPolicy Policy;
+ const ASTContext &Context;
unsigned Indentation;
bool PrintInstantiation;
@@ -36,6 +37,8 @@ namespace {
void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls);
void Print(AccessSpecifier AS);
+ void PrintConstructorInitializers(CXXConstructorDecl *CDecl,
+ std::string &Proto);
/// Print an Objective-C method type in parentheses.
///
@@ -48,9 +51,10 @@ namespace {
public:
DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
- unsigned Indentation = 0, bool PrintInstantiation = false)
- : Out(Out), Policy(Policy), Indentation(Indentation),
- PrintInstantiation(PrintInstantiation) { }
+ const ASTContext &Context, unsigned Indentation = 0,
+ bool PrintInstantiation = false)
+ : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
+ PrintInstantiation(PrintInstantiation) {}
void VisitDeclContext(DeclContext *DC, bool Indent = true);
@@ -115,7 +119,8 @@ void Decl::print(raw_ostream &Out, unsigned Indentation,
void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation, bool PrintInstantiation) const {
- DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
+ DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
+ PrintInstantiation);
Printer.Visit(const_cast<Decl*>(this));
}
@@ -192,7 +197,7 @@ LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
DC = DC->getParent();
ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
- DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0);
+ DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
}
@@ -271,6 +276,71 @@ void DeclPrinter::Print(AccessSpecifier AS) {
}
}
+void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl,
+ std::string &Proto) {
+ bool HasInitializerList = false;
+ for (const auto *BMInitializer : CDecl->inits()) {
+ if (BMInitializer->isInClassMemberInitializer())
+ continue;
+
+ if (!HasInitializerList) {
+ Proto += " : ";
+ Out << Proto;
+ Proto.clear();
+ HasInitializerList = true;
+ } else
+ Out << ", ";
+
+ if (BMInitializer->isAnyMemberInitializer()) {
+ FieldDecl *FD = BMInitializer->getAnyMember();
+ Out << *FD;
+ } else {
+ Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
+ }
+
+ Out << "(";
+ if (!BMInitializer->getInit()) {
+ // Nothing to print
+ } else {
+ Expr *Init = BMInitializer->getInit();
+ if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
+ Init = Tmp->getSubExpr();
+
+ Init = Init->IgnoreParens();
+
+ Expr *SimpleInit = nullptr;
+ Expr **Args = nullptr;
+ unsigned NumArgs = 0;
+ if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
+ Args = ParenList->getExprs();
+ NumArgs = ParenList->getNumExprs();
+ } else if (CXXConstructExpr *Construct =
+ dyn_cast<CXXConstructExpr>(Init)) {
+ Args = Construct->getArgs();
+ NumArgs = Construct->getNumArgs();
+ } else
+ SimpleInit = Init;
+
+ if (SimpleInit)
+ SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
+ else {
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ assert(Args[I] != nullptr && "Expected non-null Expr");
+ if (isa<CXXDefaultArgExpr>(Args[I]))
+ break;
+
+ if (I)
+ Out << ", ";
+ Args[I]->printPretty(Out, nullptr, Policy, Indentation);
+ }
+ }
+ }
+ Out << ")";
+ if (BMInitializer->isPackExpansion())
+ Out << "...";
+ }
+}
+
//----------------------------------------------------------------------------
// Common C declarations
//----------------------------------------------------------------------------
@@ -467,7 +537,7 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
prettyPrintAttributes(D);
if (Expr *Init = D->getInitExpr()) {
Out << " = ";
- Init->printPretty(Out, nullptr, Policy, Indentation);
+ Init->printPretty(Out, nullptr, Policy, Indentation, &Context);
}
}
@@ -510,18 +580,24 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
PrintingPolicy SubPolicy(Policy);
SubPolicy.SuppressSpecifiers = false;
std::string Proto;
- if (!Policy.SuppressScope) {
- if (const NestedNameSpecifier *NS = D->getQualifier()) {
- llvm::raw_string_ostream OS(Proto);
- NS->print(OS, Policy);
+
+ if (Policy.FullyQualifiedName) {
+ Proto += D->getQualifiedNameAsString();
+ } else {
+ if (!Policy.SuppressScope) {
+ if (const NestedNameSpecifier *NS = D->getQualifier()) {
+ llvm::raw_string_ostream OS(Proto);
+ NS->print(OS, Policy);
+ }
}
+ Proto += D->getNameInfo().getAsString();
}
- Proto += D->getNameInfo().getAsString();
+
if (GuideDecl)
Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
llvm::raw_string_ostream POut(Proto);
- DeclPrinter TArgPrinter(POut, SubPolicy, Indentation);
+ DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
TArgPrinter.printTemplateArguments(*TArgs);
}
@@ -539,7 +615,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Proto += "(";
if (FT) {
llvm::raw_string_ostream POut(Proto);
- DeclPrinter ParamPrinter(POut, SubPolicy, Indentation);
+ DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
if (i) POut << ", ";
ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
@@ -605,67 +681,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
}
if (CDecl) {
- bool HasInitializerList = false;
- for (const auto *BMInitializer : CDecl->inits()) {
- if (BMInitializer->isInClassMemberInitializer())
- continue;
-
- if (!HasInitializerList) {
- Proto += " : ";
- Out << Proto;
- Proto.clear();
- HasInitializerList = true;
- } else
- Out << ", ";
-
- if (BMInitializer->isAnyMemberInitializer()) {
- FieldDecl *FD = BMInitializer->getAnyMember();
- Out << *FD;
- } else {
- Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
- }
-
- Out << "(";
- if (!BMInitializer->getInit()) {
- // Nothing to print
- } else {
- Expr *Init = BMInitializer->getInit();
- if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
- Init = Tmp->getSubExpr();
-
- Init = Init->IgnoreParens();
-
- Expr *SimpleInit = nullptr;
- Expr **Args = nullptr;
- unsigned NumArgs = 0;
- if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
- Args = ParenList->getExprs();
- NumArgs = ParenList->getNumExprs();
- } else if (CXXConstructExpr *Construct
- = dyn_cast<CXXConstructExpr>(Init)) {
- Args = Construct->getArgs();
- NumArgs = Construct->getNumArgs();
- } else
- SimpleInit = Init;
-
- if (SimpleInit)
- SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
- else {
- for (unsigned I = 0; I != NumArgs; ++I) {
- assert(Args[I] != nullptr && "Expected non-null Expr");
- if (isa<CXXDefaultArgExpr>(Args[I]))
- break;
-
- if (I)
- Out << ", ";
- Args[I]->printPretty(Out, nullptr, Policy, Indentation);
- }
- }
- }
- Out << ")";
- if (BMInitializer->isPackExpansion())
- Out << "...";
- }
+ if (!Policy.TerseOutput)
+ PrintConstructorInitializers(CDecl, Proto);
} else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
if (FT && FT->hasTrailingReturn()) {
if (!GuideDecl)
@@ -695,7 +712,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
// This is a K&R function definition, so we need to print the
// parameters.
Out << '\n';
- DeclPrinter ParamPrinter(Out, SubPolicy, Indentation);
+ DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
Indentation += Policy.Indentation;
for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
Indent();
@@ -709,7 +726,7 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (D->getBody())
D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
} else {
- if (isa<CXXConstructorDecl>(*D))
+ if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D))
Out << " {}";
}
}
@@ -1541,7 +1558,19 @@ void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Out << ")";
if (auto *Init = D->getInitializer()) {
Out << " initializer(";
+ switch (D->getInitializerKind()) {
+ case OMPDeclareReductionDecl::DirectInit:
+ Out << "omp_priv(";
+ break;
+ case OMPDeclareReductionDecl::CopyInit:
+ Out << "omp_priv = ";
+ break;
+ case OMPDeclareReductionDecl::CallInit:
+ break;
+ }
Init->printPretty(Out, nullptr, Policy, 0);
+ if (D->getInitializerKind() == OMPDeclareReductionDecl::DirectInit)
+ Out << ")";
Out << ")";
}
}
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 00a6739478bd..a7949b310cef 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -1,4 +1,4 @@
-//===--- DeclTemplate.cpp - Template Declaration AST Node Implementation --===//
+//===- DeclTemplate.cpp - Template Declaration AST Node Implementation ----===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,13 +15,28 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Builtins.h"
-#include "clang/Basic/IdentifierTable.h"
-#include "llvm/ADT/STLExtras.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
#include <memory>
+#include <utility>
+
using namespace clang;
//===----------------------------------------------------------------------===//
@@ -33,9 +48,9 @@ TemplateParameterList::TemplateParameterList(SourceLocation TemplateLoc,
ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc,
Expr *RequiresClause)
- : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
- NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
- HasRequiresClause(static_cast<bool>(RequiresClause)) {
+ : TemplateLoc(TemplateLoc), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc),
+ NumParams(Params.size()), ContainsUnexpandedParameterPack(false),
+ HasRequiresClause(static_cast<bool>(RequiresClause)) {
for (unsigned Idx = 0; Idx < NumParams; ++Idx) {
NamedDecl *P = Params[Idx];
begin()[Idx] = P;
@@ -124,10 +139,12 @@ static void AdoptTemplateParameterList(TemplateParameterList *Params,
}
namespace clang {
+
void *allocateDefaultArgStorageChain(const ASTContext &C) {
return new (C) char[sizeof(void*) * 2];
}
-}
+
+} // namespace clang
//===----------------------------------------------------------------------===//
// RedeclarableTemplateDecl Implementation
@@ -165,14 +182,28 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c
return Common;
}
+void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const {
+ // Grab the most recent declaration to ensure we've loaded any lazy
+ // redeclarations of this template.
+ CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr();
+ if (CommonBasePtr->LazySpecializations) {
+ ASTContext &Context = getASTContext();
+ uint32_t *Specs = CommonBasePtr->LazySpecializations;
+ CommonBasePtr->LazySpecializations = nullptr;
+ for (uint32_t I = 0, N = *Specs++; I != N; ++I)
+ (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
+ }
+}
+
template<class EntryType>
typename RedeclarableTemplateDecl::SpecEntryTraits<EntryType>::DeclType *
RedeclarableTemplateDecl::findSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specs, ArrayRef<TemplateArgument> Args,
void *&InsertPos) {
- typedef SpecEntryTraits<EntryType> SETraits;
+ using SETraits = SpecEntryTraits<EntryType>;
+
llvm::FoldingSetNodeID ID;
- EntryType::Profile(ID,Args, getASTContext());
+ EntryType::Profile(ID, Args, getASTContext());
EntryType *Entry = Specs.FindNodeOrInsertPos(ID, InsertPos);
return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr;
}
@@ -181,7 +212,8 @@ template<class Derived, class EntryType>
void RedeclarableTemplateDecl::addSpecializationImpl(
llvm::FoldingSetVector<EntryType> &Specializations, EntryType *Entry,
void *InsertPos) {
- typedef SpecEntryTraits<EntryType> SETraits;
+ using SETraits = SpecEntryTraits<EntryType>;
+
if (InsertPos) {
#ifndef NDEBUG
void *CorrectInsertPos;
@@ -232,18 +264,7 @@ FunctionTemplateDecl::newCommon(ASTContext &C) const {
}
void FunctionTemplateDecl::LoadLazySpecializations() const {
- // Grab the most recent declaration to ensure we've loaded any lazy
- // redeclarations of this template.
- //
- // FIXME: Avoid walking the entire redeclaration chain here.
- Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
- if (CommonPtr->LazySpecializations) {
- ASTContext &Context = getASTContext();
- uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = nullptr;
- for (uint32_t I = 0, N = *Specs++; I != N; ++I)
- (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
- }
+ loadLazySpecializationsImpl();
}
llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
@@ -311,18 +332,7 @@ ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C,
}
void ClassTemplateDecl::LoadLazySpecializations() const {
- // Grab the most recent declaration to ensure we've loaded any lazy
- // redeclarations of this template.
- //
- // FIXME: Avoid walking the entire redeclaration chain here.
- Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
- if (CommonPtr->LazySpecializations) {
- ASTContext &Context = getASTContext();
- uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = nullptr;
- for (uint32_t I = 0, N = *Specs++; I != N; ++I)
- (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
- }
+ loadLazySpecializationsImpl();
}
llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
@@ -562,7 +572,7 @@ SourceLocation NonTypeTemplateParmDecl::getDefaultArgumentLoc() const {
// TemplateTemplateParmDecl Method Implementations
//===----------------------------------------------------------------------===//
-void TemplateTemplateParmDecl::anchor() { }
+void TemplateTemplateParmDecl::anchor() {}
TemplateTemplateParmDecl::TemplateTemplateParmDecl(
DeclContext *DC, SourceLocation L, unsigned D, unsigned P,
@@ -665,11 +675,12 @@ FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
// TemplateDecl Implementation
//===----------------------------------------------------------------------===//
-void TemplateDecl::anchor() { }
+void TemplateDecl::anchor() {}
//===----------------------------------------------------------------------===//
// ClassTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
+
ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
@@ -677,11 +688,9 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
ClassTemplateDecl *SpecializedTemplate,
ArrayRef<TemplateArgument> Args,
ClassTemplateSpecializationDecl *PrevDecl)
- : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
- SpecializedTemplate->getIdentifier(),
- PrevDecl),
+ : CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
+ SpecializedTemplate->getIdentifier(), PrevDecl),
SpecializedTemplate(SpecializedTemplate),
- ExplicitInfo(nullptr),
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
SpecializationKind(TSK_Undeclared) {
}
@@ -690,7 +699,7 @@ ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
Kind DK)
: CXXRecordDecl(DK, TTK_Struct, C, nullptr, SourceLocation(),
SourceLocation(), nullptr, nullptr),
- ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
+ SpecializationKind(TSK_Undeclared) {}
ClassTemplateSpecializationDecl *
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
@@ -726,12 +735,10 @@ void ClassTemplateSpecializationDecl::getNameForDiagnostic(
auto *PS = dyn_cast<ClassTemplatePartialSpecializationDecl>(this);
if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
PS ? PS->getTemplateArgsAsWritten() : nullptr) {
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, ArgsAsWritten->arguments(), Policy);
+ printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
} else {
const TemplateArgumentList &TemplateArgs = getTemplateArgs();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs.asArray(), Policy);
+ printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
}
}
@@ -762,7 +769,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const {
// An implicit instantiation of a class template partial specialization
// uses ExplicitInfo to record the TypeAsWritten, but the source
// locations should be retrieved from the instantiation pattern.
- typedef ClassTemplatePartialSpecializationDecl CTPSDecl;
+ using CTPSDecl = ClassTemplatePartialSpecializationDecl;
CTPSDecl *ctpsd = const_cast<CTPSDecl*>(cast<CTPSDecl>(this));
CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
assert(inst_from != nullptr);
@@ -785,7 +792,7 @@ ClassTemplateSpecializationDecl::getSourceRange() const {
//===----------------------------------------------------------------------===//
// ClassTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
-void ClassTemplatePartialSpecializationDecl::anchor() { }
+void ClassTemplatePartialSpecializationDecl::anchor() {}
ClassTemplatePartialSpecializationDecl::
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
@@ -797,14 +804,12 @@ ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
ArrayRef<TemplateArgument> Args,
const ASTTemplateArgumentListInfo *ArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl)
- : ClassTemplateSpecializationDecl(Context,
- ClassTemplatePartialSpecialization,
- TK, DC, StartLoc, IdLoc,
- SpecializedTemplate,
- Args, PrevDecl),
- TemplateParams(Params), ArgsAsWritten(ArgInfos),
- InstantiatedFromMember(nullptr, false)
-{
+ : ClassTemplateSpecializationDecl(Context,
+ ClassTemplatePartialSpecialization,
+ TK, DC, StartLoc, IdLoc,
+ SpecializedTemplate, Args, PrevDecl),
+ TemplateParams(Params), ArgsAsWritten(ArgInfos),
+ InstantiatedFromMember(nullptr, false) {
AdoptTemplateParameterList(Params, this);
}
@@ -845,7 +850,7 @@ ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//
-void FriendTemplateDecl::anchor() { }
+void FriendTemplateDecl::anchor() {}
FriendTemplateDecl *
FriendTemplateDecl::Create(ASTContext &Context, DeclContext *DC,
@@ -891,7 +896,7 @@ TypeAliasTemplateDecl::newCommon(ASTContext &C) const {
// ClassScopeFunctionSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
-void ClassScopeFunctionSpecializationDecl::anchor() { }
+void ClassScopeFunctionSpecializationDecl::anchor() {}
ClassScopeFunctionSpecializationDecl *
ClassScopeFunctionSpecializationDecl::CreateDeserialized(ASTContext &C,
@@ -927,21 +932,8 @@ VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C,
DeclarationName(), nullptr, nullptr);
}
-// TODO: Unify across class, function and variable templates?
-// May require moving this and Common to RedeclarableTemplateDecl.
void VarTemplateDecl::LoadLazySpecializations() const {
- // Grab the most recent declaration to ensure we've loaded any lazy
- // redeclarations of this template.
- //
- // FIXME: Avoid walking the entire redeclaration chain here.
- Common *CommonPtr = getMostRecentDecl()->getCommonPtr();
- if (CommonPtr->LazySpecializations) {
- ASTContext &Context = getASTContext();
- uint32_t *Specs = CommonPtr->LazySpecializations;
- CommonPtr->LazySpecializations = nullptr;
- for (uint32_t I = 0, N = *Specs++; I != N; ++I)
- (void)Context.getExternalSource()->GetExternalDecl(Specs[I]);
- }
+ loadLazySpecializationsImpl();
}
llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
@@ -1020,21 +1012,22 @@ VarTemplateDecl::findPartialSpecInstantiatedFromMember(
//===----------------------------------------------------------------------===//
// VarTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
+
VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(
Kind DK, ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args)
: VarDecl(DK, Context, DC, StartLoc, IdLoc,
SpecializedTemplate->getIdentifier(), T, TInfo, S),
- SpecializedTemplate(SpecializedTemplate), ExplicitInfo(nullptr),
+ SpecializedTemplate(SpecializedTemplate),
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
- SpecializationKind(TSK_Undeclared) {}
+ SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
VarTemplateSpecializationDecl::VarTemplateSpecializationDecl(Kind DK,
ASTContext &C)
: VarDecl(DK, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
QualType(), nullptr, SC_None),
- ExplicitInfo(nullptr), SpecializationKind(TSK_Undeclared) {}
+ SpecializationKind(TSK_Undeclared), IsCompleteDefinition(false) {}
VarTemplateSpecializationDecl *VarTemplateSpecializationDecl::Create(
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
@@ -1058,12 +1051,10 @@ void VarTemplateSpecializationDecl::getNameForDiagnostic(
auto *PS = dyn_cast<VarTemplatePartialSpecializationDecl>(this);
if (const ASTTemplateArgumentListInfo *ArgsAsWritten =
PS ? PS->getTemplateArgsAsWritten() : nullptr) {
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, ArgsAsWritten->arguments(), Policy);
+ printTemplateArgumentList(OS, ArgsAsWritten->arguments(), Policy);
} else {
const TemplateArgumentList &TemplateArgs = getTemplateArgs();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs.asArray(), Policy);
+ printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
}
}
@@ -1085,6 +1076,7 @@ void VarTemplateSpecializationDecl::setTemplateArgsInfo(
//===----------------------------------------------------------------------===//
// VarTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
+
void VarTemplatePartialSpecializationDecl::anchor() {}
VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 1f8e26deda97..31bae93c3cb5 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -1,4 +1,4 @@
-//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
+//===- DeclarationName.cpp - Declaration names implementation -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,20 +11,36 @@
// classes.
//
//===----------------------------------------------------------------------===//
+
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <string>
+
using namespace clang;
namespace clang {
+
/// CXXSpecialName - Records the type associated with one of the
/// "special" kinds of declaration names in C++, e.g., constructors,
/// destructors, and conversion functions.
@@ -89,6 +105,8 @@ public:
}
};
+} // namespace clang
+
static int compareInt(unsigned A, unsigned B) {
return (A < B ? -1 : (A > B ? 1 : 0));
}
@@ -197,10 +215,9 @@ void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
case DeclarationName::CXXConstructorName:
return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
- case DeclarationName::CXXDestructorName: {
+ case DeclarationName::CXXDestructorName:
OS << '~';
return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy);
- }
case DeclarationName::CXXDeductionGuideName:
OS << "<deduction guide for ";
@@ -250,13 +267,15 @@ void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
llvm_unreachable("Unexpected declaration name kind");
}
+namespace clang {
+
raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
LangOptions LO;
N.print(OS, PrintingPolicy(LO));
return OS;
}
-} // end namespace clang
+} // namespace clang
DeclarationName::NameKind DeclarationName::getNameKind() const {
switch (getStoredNameKind()) {
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index afc7fa8ea094..55061aa462e5 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1695,6 +1695,26 @@ CXXBaseSpecifier **CastExpr::path_buffer() {
}
}
+const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
+ QualType opType) {
+ auto RD = unionType->castAs<RecordType>()->getDecl();
+ return getTargetFieldForToUnionCast(RD, opType);
+}
+
+const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
+ QualType OpType) {
+ auto &Ctx = RD->getASTContext();
+ RecordDecl::field_iterator Field, FieldEnd;
+ for (Field = RD->field_begin(), FieldEnd = RD->field_end();
+ Field != FieldEnd; ++Field) {
+ if (Ctx.hasSameUnqualifiedType(Field->getType(), OpType) &&
+ !Field->isUnnamedBitfield()) {
+ return *Field;
+ }
+ }
+ return nullptr;
+}
+
ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
CastKind Kind, Expr *Operand,
const CXXCastPath *BasePath,
@@ -1760,6 +1780,7 @@ BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
case OO_Amp: return BO_And;
case OO_Pipe: return BO_Or;
case OO_Equal: return BO_Assign;
+ case OO_Spaceship: return BO_Cmp;
case OO_Less: return BO_LT;
case OO_Greater: return BO_GT;
case OO_PlusEqual: return BO_AddAssign;
@@ -1791,6 +1812,7 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
OO_Star, OO_Slash, OO_Percent,
OO_Plus, OO_Minus,
OO_LessLess, OO_GreaterGreater,
+ OO_Spaceship,
OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
OO_EqualEqual, OO_ExclaimEqual,
OO_Amp,
@@ -1809,6 +1831,38 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
return OverOps[Opc];
}
+bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
+ Opcode Opc,
+ Expr *LHS, Expr *RHS) {
+ if (Opc != BO_Add)
+ return false;
+
+ // Check that we have one pointer and one integer operand.
+ Expr *PExp;
+ if (LHS->getType()->isPointerType()) {
+ if (!RHS->getType()->isIntegerType())
+ return false;
+ PExp = LHS;
+ } else if (RHS->getType()->isPointerType()) {
+ if (!LHS->getType()->isIntegerType())
+ return false;
+ PExp = RHS;
+ } else {
+ return false;
+ }
+
+ // Check that the pointer is a nullptr.
+ if (!PExp->IgnoreParenCasts()
+ ->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
+ return false;
+
+ // Check that the pointee type is char-sized.
+ const PointerType *PTy = PExp->getType()->getAs<PointerType>();
+ if (!PTy || !PTy->getPointeeType()->isCharType())
+ return false;
+
+ return true;
+}
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
@@ -1899,6 +1953,17 @@ bool InitListExpr::isTransparent() const {
getInit(0)->getType().getCanonicalType();
}
+bool InitListExpr::isIdiomaticZeroInitializer(const LangOptions &LangOpts) const {
+ assert(isSyntacticForm() && "only test syntactic form as zero initializer");
+
+ if (LangOpts.CPlusPlus || getNumInits() != 1) {
+ return false;
+ }
+
+ const IntegerLiteral *Lit = dyn_cast<IntegerLiteral>(getInit(0));
+ return Lit && Lit->getValue() == 0;
+}
+
SourceLocation InitListExpr::getLocStart() const {
if (InitListExpr *SyntacticForm = getSyntacticForm())
return SyntacticForm->getLocStart();
@@ -2235,7 +2300,8 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
const DeclRefExpr *DRE =
dyn_cast<DeclRefExpr>(CE->getSubExpr()->IgnoreParens());
if (!(DRE && isa<VarDecl>(DRE->getDecl()) &&
- cast<VarDecl>(DRE->getDecl())->hasLocalStorage())) {
+ cast<VarDecl>(DRE->getDecl())->hasLocalStorage()) &&
+ !isa<CallExpr>(CE->getSubExpr()->IgnoreParens())) {
return CE->getSubExpr()->isUnusedResultAWarning(WarnE, Loc,
R1, R2, Ctx);
}
@@ -3230,20 +3296,20 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
// Check that it is a cast to void*.
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
QualType Pointee = PT->getPointeeType();
- Qualifiers Q = Pointee.getQualifiers();
- // In OpenCL v2.0 generic address space acts as a placeholder
- // and should be ignored.
- bool IsASValid = true;
- if (Ctx.getLangOpts().OpenCLVersion >= 200) {
- if (Pointee.getAddressSpace() == LangAS::opencl_generic)
- Q.removeAddressSpace();
- else
- IsASValid = false;
- }
-
- if (IsASValid && !Q.hasQualifiers() &&
- Pointee->isVoidType() && // to void*
- CE->getSubExpr()->getType()->isIntegerType()) // from int.
+ // Only (void*)0 or equivalent are treated as nullptr. If pointee type
+ // has non-default address space it is not treated as nullptr.
+ // (__generic void*)0 in OpenCL 2.0 should not be treated as nullptr
+ // since it cannot be assigned to a pointer to constant address space.
+ bool PointeeHasDefaultAS =
+ Pointee.getAddressSpace() == LangAS::Default ||
+ (Ctx.getLangOpts().OpenCLVersion >= 200 &&
+ Pointee.getAddressSpace() == LangAS::opencl_generic) ||
+ (Ctx.getLangOpts().OpenCL &&
+ Ctx.getLangOpts().OpenCLVersion < 200 &&
+ Pointee.getAddressSpace() == LangAS::opencl_private);
+
+ if (PointeeHasDefaultAS && Pointee->isVoidType() && // to void*
+ CE->getSubExpr()->getType()->isIntegerType()) // from int.
return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
}
}
@@ -3938,10 +4004,12 @@ AtomicExpr::AtomicExpr(SourceLocation BLoc, ArrayRef<Expr*> args,
unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
switch (Op) {
case AO__c11_atomic_init:
+ case AO__opencl_atomic_init:
case AO__c11_atomic_load:
case AO__atomic_load_n:
return 2;
+ case AO__opencl_atomic_load:
case AO__c11_atomic_store:
case AO__c11_atomic_exchange:
case AO__atomic_load:
@@ -3967,6 +4035,15 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__atomic_nand_fetch:
return 3;
+ case AO__opencl_atomic_store:
+ case AO__opencl_atomic_exchange:
+ case AO__opencl_atomic_fetch_add:
+ case AO__opencl_atomic_fetch_sub:
+ case AO__opencl_atomic_fetch_and:
+ case AO__opencl_atomic_fetch_or:
+ case AO__opencl_atomic_fetch_xor:
+ case AO__opencl_atomic_fetch_min:
+ case AO__opencl_atomic_fetch_max:
case AO__atomic_exchange:
return 4;
@@ -3974,6 +4051,8 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
case AO__c11_atomic_compare_exchange_weak:
return 5;
+ case AO__opencl_atomic_compare_exchange_strong:
+ case AO__opencl_atomic_compare_exchange_weak:
case AO__atomic_compare_exchange:
case AO__atomic_compare_exchange_n:
return 6;
@@ -3981,6 +4060,13 @@ unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
llvm_unreachable("unknown atomic op");
}
+QualType AtomicExpr::getValueType() const {
+ auto T = getPtr()->getType()->castAs<PointerType>()->getPointeeType();
+ if (auto AT = T->getAs<AtomicType>())
+ return AT->getValueType();
+ return T;
+}
+
QualType OMPArraySectionExpr::getBaseOriginalType(const Expr *Base) {
unsigned ArraySectionCount = 0;
while (auto *OASE = dyn_cast<OMPArraySectionExpr>(Base->IgnoreParens())) {
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index fe45b5e47f36..262a1e3ff9d5 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -1,4 +1,4 @@
-//===--- ExprCXX.cpp - (C++) Expression AST Node Implementation -----------===//
+//===- ExprCXX.cpp - (C++) Expression AST Node Implementation -------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,15 +11,33 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclAccessPair.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/ExprCXX.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/LambdaCapture.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/IdentifierTable.h"
-using namespace clang;
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <memory>
+using namespace clang;
//===----------------------------------------------------------------------===//
// Child Iterators for iterating over subexpressions/substatements
@@ -85,15 +103,14 @@ CXXNewExpr::CXXNewExpr(const ASTContext &C, bool globalNew,
Expr *initializer, QualType ty,
TypeSourceInfo *allocatedTypeInfo,
SourceRange Range, SourceRange directInitRange)
- : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), ty->isDependentType(),
- ty->isInstantiationDependentType(),
- ty->containsUnexpandedParameterPack()),
- SubExprs(nullptr), OperatorNew(operatorNew), OperatorDelete(operatorDelete),
- AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
- Range(Range), DirectInitRange(directInitRange),
- GlobalNew(globalNew), PassAlignment(PassAlignment),
- UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {
+ : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(),
+ ty->isDependentType(), ty->isInstantiationDependentType(),
+ ty->containsUnexpandedParameterPack()),
+ OperatorNew(operatorNew), OperatorDelete(operatorDelete),
+ AllocatedTypeInfo(allocatedTypeInfo), TypeIdParens(typeIdParens),
+ Range(Range), DirectInitRange(directInitRange), GlobalNew(globalNew),
+ PassAlignment(PassAlignment),
+ UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) {
assert((initializer != nullptr || initializationStyle == NoInit) &&
"Only NoInit can have no initializer.");
StoredInitializationStyle = initializer ? initializationStyle + 1 : 0;
@@ -160,6 +177,22 @@ bool CXXNewExpr::shouldNullCheckAllocation(const ASTContext &Ctx) const {
// CXXDeleteExpr
QualType CXXDeleteExpr::getDestroyedType() const {
const Expr *Arg = getArgument();
+
+ // For a destroying operator delete, we may have implicitly converted the
+ // pointer type to the type of the parameter of the 'operator delete'
+ // function.
+ while (auto *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
+ if (ICE->getCastKind() == CK_DerivedToBase ||
+ ICE->getCastKind() == CK_UncheckedDerivedToBase ||
+ ICE->getCastKind() == CK_NoOp) {
+ assert((ICE->getCastKind() == CK_NoOp ||
+ getOperatorDelete()->isDestroyingOperatorDelete()) &&
+ "only a destroying operator delete can have a converted arg");
+ Arg = ICE->getSubExpr();
+ } else
+ break;
+ }
+
// The type-to-delete may not be a pointer if it's a dependent type.
const QualType ArgType = Arg->getType();
@@ -171,8 +204,7 @@ QualType CXXDeleteExpr::getDestroyedType() const {
// CXXPseudoDestructorExpr
PseudoDestructorTypeStorage::PseudoDestructorTypeStorage(TypeSourceInfo *Info)
- : Type(Info)
-{
+ : Type(Info) {
Location = Info->getTypeLoc().getLocalSourceRange().getBegin();
}
@@ -209,7 +241,7 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(const ASTContext &Context,
Base(static_cast<Stmt *>(Base)), IsArrow(isArrow),
OperatorLoc(OperatorLoc), QualifierLoc(QualifierLoc),
ScopeType(ScopeType), ColonColonLoc(ColonColonLoc), TildeLoc(TildeLoc),
- DestroyedType(DestroyedType) { }
+ DestroyedType(DestroyedType) {}
QualType CXXPseudoDestructorExpr::getDestroyedType() const {
if (TypeSourceInfo *TInfo = DestroyedType.getTypeSourceInfo())
@@ -235,8 +267,7 @@ UnresolvedLookupExpr::Create(const ASTContext &C,
bool ADL,
const TemplateArgumentListInfo *Args,
UnresolvedSetIterator Begin,
- UnresolvedSetIterator End)
-{
+ UnresolvedSetIterator End) {
assert(Args || TemplateKWLoc.isValid());
unsigned num_args = Args ? Args->size() : 0;
@@ -274,21 +305,20 @@ OverloadExpr::OverloadExpr(StmtClass K, const ASTContext &C,
bool KnownDependent,
bool KnownInstantiationDependent,
bool KnownContainsUnexpandedParameterPack)
- : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
- KnownDependent,
- (KnownInstantiationDependent ||
- NameInfo.isInstantiationDependent() ||
- (QualifierLoc &&
- QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
- (KnownContainsUnexpandedParameterPack ||
- NameInfo.containsUnexpandedParameterPack() ||
- (QualifierLoc &&
- QualifierLoc.getNestedNameSpecifier()
- ->containsUnexpandedParameterPack()))),
- NameInfo(NameInfo), QualifierLoc(QualifierLoc),
- Results(nullptr), NumResults(End - Begin),
- HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
- TemplateKWLoc.isValid()) {
+ : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent,
+ KnownDependent,
+ (KnownInstantiationDependent ||
+ NameInfo.isInstantiationDependent() ||
+ (QualifierLoc &&
+ QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())),
+ (KnownContainsUnexpandedParameterPack ||
+ NameInfo.containsUnexpandedParameterPack() ||
+ (QualifierLoc &&
+ QualifierLoc.getNestedNameSpecifier()
+ ->containsUnexpandedParameterPack()))),
+ NameInfo(NameInfo), QualifierLoc(QualifierLoc), NumResults(End - Begin),
+ HasTemplateKWAndArgsInfo(TemplateArgs != nullptr ||
+ TemplateKWLoc.isValid()) {
NumResults = End - Begin;
if (NumResults) {
// Determine whether this expression is type-dependent.
@@ -493,7 +523,6 @@ CXXMethodDecl *CXXMemberCallExpr::getMethodDecl() const {
return nullptr;
}
-
CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() const {
Expr* ThisArg = getImplicitObjectArgument();
if (!ThisArg)
@@ -505,7 +534,6 @@ CXXRecordDecl *CXXMemberCallExpr::getRecordDecl() const {
return ThisArg->getType()->getAsCXXRecordDecl();
}
-
//===----------------------------------------------------------------------===//
// Named casts
//===----------------------------------------------------------------------===//
@@ -742,16 +770,12 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
bool ListInitialization,
bool StdInitListInitialization,
bool ZeroInitialization)
- : CXXConstructExpr(C, CXXTemporaryObjectExprClass, Type,
- TSI->getTypeLoc().getBeginLoc(),
- Cons, false, Args,
- HadMultipleCandidates,
- ListInitialization,
- StdInitListInitialization,
- ZeroInitialization,
- CXXConstructExpr::CK_Complete, ParenOrBraceRange),
- Type(TSI) {
-}
+ : CXXConstructExpr(C, CXXTemporaryObjectExprClass, Type,
+ TSI->getTypeLoc().getBeginLoc(), Cons, false, Args,
+ HadMultipleCandidates, ListInitialization,
+ StdInitListInitialization, ZeroInitialization,
+ CXXConstructExpr::CK_Complete, ParenOrBraceRange),
+ Type(TSI) {}
SourceLocation CXXTemporaryObjectExpr::getLocStart() const {
return Type->getTypeLoc().getBeginLoc();
@@ -794,18 +818,16 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange)
- : Expr(SC, T, VK_RValue, OK_Ordinary,
- T->isDependentType(), T->isDependentType(),
- T->isInstantiationDependentType(),
- T->containsUnexpandedParameterPack()),
- Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
- NumArgs(Args.size()),
- Elidable(Elidable), HadMultipleCandidates(HadMultipleCandidates),
- ListInitialization(ListInitialization),
- StdInitListInitialization(StdInitListInitialization),
- ZeroInitialization(ZeroInitialization),
- ConstructKind(ConstructKind), Args(nullptr)
-{
+ : Expr(SC, T, VK_RValue, OK_Ordinary,
+ T->isDependentType(), T->isDependentType(),
+ T->isInstantiationDependentType(),
+ T->containsUnexpandedParameterPack()),
+ Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
+ NumArgs(Args.size()), Elidable(Elidable),
+ HadMultipleCandidates(HadMultipleCandidates),
+ ListInitialization(ListInitialization),
+ StdInitListInitialization(StdInitListInitialization),
+ ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind) {
if (NumArgs) {
this->Args = new (C) Stmt*[Args.size()];
@@ -827,8 +849,7 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
LambdaCapture::LambdaCapture(SourceLocation Loc, bool Implicit,
LambdaCaptureKind Kind, VarDecl *Var,
SourceLocation EllipsisLoc)
- : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc)
-{
+ : DeclAndBits(Var, 0), Loc(Loc), EllipsisLoc(EllipsisLoc) {
unsigned Bits = 0;
if (Implicit)
Bits |= Capture_Implicit;
@@ -995,7 +1016,7 @@ CompoundStmt *LambdaExpr::getBody() const {
// initialized in ASTStmtReader::VisitLambdaExpr, but for reasons I
// don't understand, that doesn't work.
if (!getStoredStmts()[NumCaptures])
- *const_cast<clang::Stmt **>(&getStoredStmts()[NumCaptures]) =
+ *const_cast<Stmt **>(&getStoredStmts()[NumCaptures]) =
getCallOperator()->getBody();
return static_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]);
@@ -1008,12 +1029,12 @@ bool LambdaExpr::isMutable() const {
ExprWithCleanups::ExprWithCleanups(Expr *subexpr,
bool CleanupsHaveSideEffects,
ArrayRef<CleanupObject> objects)
- : Expr(ExprWithCleanupsClass, subexpr->getType(),
- subexpr->getValueKind(), subexpr->getObjectKind(),
- subexpr->isTypeDependent(), subexpr->isValueDependent(),
- subexpr->isInstantiationDependent(),
- subexpr->containsUnexpandedParameterPack()),
- SubExpr(subexpr) {
+ : Expr(ExprWithCleanupsClass, subexpr->getType(),
+ subexpr->getValueKind(), subexpr->getObjectKind(),
+ subexpr->isTypeDependent(), subexpr->isValueDependent(),
+ subexpr->isInstantiationDependent(),
+ subexpr->containsUnexpandedParameterPack()),
+ SubExpr(subexpr) {
ExprWithCleanupsBits.CleanupsHaveSideEffects = CleanupsHaveSideEffects;
ExprWithCleanupsBits.NumObjects = objects.size();
for (unsigned i = 0, e = objects.size(); i != e; ++i)
@@ -1030,7 +1051,7 @@ ExprWithCleanups *ExprWithCleanups::Create(const ASTContext &C, Expr *subexpr,
}
ExprWithCleanups::ExprWithCleanups(EmptyShell empty, unsigned numObjects)
- : Expr(ExprWithCleanupsClass, empty) {
+ : Expr(ExprWithCleanupsClass, empty) {
ExprWithCleanupsBits.NumObjects = numObjects;
}
@@ -1046,20 +1067,18 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type,
SourceLocation LParenLoc,
ArrayRef<Expr*> Args,
SourceLocation RParenLoc)
- : Expr(CXXUnresolvedConstructExprClass,
- Type->getType().getNonReferenceType(),
- (Type->getType()->isLValueReferenceType() ? VK_LValue
- :Type->getType()->isRValueReferenceType()? VK_XValue
- :VK_RValue),
- OK_Ordinary,
- Type->getType()->isDependentType() ||
- Type->getType()->getContainedDeducedType(),
- true, true,
- Type->getType()->containsUnexpandedParameterPack()),
- Type(Type),
- LParenLoc(LParenLoc),
- RParenLoc(RParenLoc),
- NumArgs(Args.size()) {
+ : Expr(CXXUnresolvedConstructExprClass,
+ Type->getType().getNonReferenceType(),
+ (Type->getType()->isLValueReferenceType()
+ ? VK_LValue
+ : Type->getType()->isRValueReferenceType() ? VK_XValue
+ : VK_RValue),
+ OK_Ordinary,
+ Type->getType()->isDependentType() ||
+ Type->getType()->getContainedDeducedType(),
+ true, true, Type->getType()->containsUnexpandedParameterPack()),
+ Type(Type), LParenLoc(LParenLoc), RParenLoc(RParenLoc),
+ NumArgs(Args.size()) {
Expr **StoredArgs = getTrailingObjects<Expr *>();
for (unsigned I = 0; I != Args.size(); ++I) {
if (Args[I]->containsUnexpandedParameterPack())
@@ -1159,7 +1178,7 @@ CXXDependentScopeMemberExpr::CreateEmpty(const ASTContext &C,
void *Mem = C.Allocate(Size, alignof(CXXDependentScopeMemberExpr));
CXXDependentScopeMemberExpr *E
= new (Mem) CXXDependentScopeMemberExpr(C, nullptr, QualType(),
- 0, SourceLocation(),
+ false, SourceLocation(),
NestedNameSpecifierLoc(),
SourceLocation(), nullptr,
DeclarationNameInfo(), nullptr);
@@ -1202,19 +1221,18 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(const ASTContext &C,
const TemplateArgumentListInfo *TemplateArgs,
UnresolvedSetIterator Begin,
UnresolvedSetIterator End)
- : OverloadExpr(UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc,
- MemberNameInfo, TemplateArgs, Begin, End,
- // Dependent
- ((Base && Base->isTypeDependent()) ||
- BaseType->isDependentType()),
- ((Base && Base->isInstantiationDependent()) ||
- BaseType->isInstantiationDependentType()),
- // Contains unexpanded parameter pack
- ((Base && Base->containsUnexpandedParameterPack()) ||
- BaseType->containsUnexpandedParameterPack())),
- IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing),
- Base(Base), BaseType(BaseType), OperatorLoc(OperatorLoc) {
-
+ : OverloadExpr(
+ UnresolvedMemberExprClass, C, QualifierLoc, TemplateKWLoc,
+ MemberNameInfo, TemplateArgs, Begin, End,
+ // Dependent
+ ((Base && Base->isTypeDependent()) || BaseType->isDependentType()),
+ ((Base && Base->isInstantiationDependent()) ||
+ BaseType->isInstantiationDependentType()),
+ // Contains unexpanded parameter pack
+ ((Base && Base->containsUnexpandedParameterPack()) ||
+ BaseType->containsUnexpandedParameterPack())),
+ IsArrow(IsArrow), HasUnresolvedUsing(HasUnresolvedUsing), Base(Base),
+ BaseType(BaseType), OperatorLoc(OperatorLoc) {
// Check whether all of the members are non-static member functions,
// and if so, mark give this bound-member type instead of overload type.
if (hasOnlyNonStaticMemberFunctions(Begin, End))
@@ -1315,10 +1333,10 @@ SubstNonTypeTemplateParmPackExpr(QualType T,
NonTypeTemplateParmDecl *Param,
SourceLocation NameLoc,
const TemplateArgument &ArgPack)
- : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary,
- true, true, true, true),
- Param(Param), Arguments(ArgPack.pack_begin()),
- NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { }
+ : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary,
+ true, true, true, true),
+ Param(Param), Arguments(ArgPack.pack_begin()),
+ NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) {}
TemplateArgument SubstNonTypeTemplateParmPackExpr::getArgumentPack() const {
return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
@@ -1374,13 +1392,12 @@ TypeTraitExpr::TypeTraitExpr(QualType T, SourceLocation Loc, TypeTrait Kind,
ArrayRef<TypeSourceInfo *> Args,
SourceLocation RParenLoc,
bool Value)
- : Expr(TypeTraitExprClass, T, VK_RValue, OK_Ordinary,
- /*TypeDependent=*/false,
- /*ValueDependent=*/false,
- /*InstantiationDependent=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- Loc(Loc), RParenLoc(RParenLoc)
-{
+ : Expr(TypeTraitExprClass, T, VK_RValue, OK_Ordinary,
+ /*TypeDependent=*/false,
+ /*ValueDependent=*/false,
+ /*InstantiationDependent=*/false,
+ /*ContainsUnexpandedParameterPack=*/false),
+ Loc(Loc), RParenLoc(RParenLoc) {
TypeTraitExprBits.Kind = Kind;
TypeTraitExprBits.Value = Value;
TypeTraitExprBits.NumArgs = Args.size();
@@ -1415,4 +1432,4 @@ TypeTraitExpr *TypeTraitExpr::CreateDeserialized(const ASTContext &C,
return new (Mem) TypeTraitExpr(EmptyShell());
}
-void ArrayTypeTraitExpr::anchor() { }
+void ArrayTypeTraitExpr::anchor() {}
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp
index d149bdd0cdf9..3bb2b4eb5fc1 100644
--- a/lib/AST/ExprClassification.cpp
+++ b/lib/AST/ExprClassification.cpp
@@ -641,7 +641,7 @@ static Cl::ModifiableType IsModifiable(ASTContext &Ctx, const Expr *E,
// Records with any const fields (recursively) are not modifiable.
if (const RecordType *R = CT->getAs<RecordType>())
if (R->hasConstFields())
- return Cl::CM_ConstQualified;
+ return Cl::CM_ConstQualifiedField;
return Cl::CM_Modifiable;
}
@@ -695,6 +695,7 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const {
llvm_unreachable("CM_LValueCast and CL_LValue don't match");
case Cl::CM_NoSetterProperty: return MLV_NoSetterProperty;
case Cl::CM_ConstQualified: return MLV_ConstQualified;
+ case Cl::CM_ConstQualifiedField: return MLV_ConstQualifiedField;
case Cl::CM_ConstAddrSpace: return MLV_ConstAddrSpace;
case Cl::CM_ArrayType: return MLV_ArrayType;
case Cl::CM_IncompleteType: return MLV_IncompleteType;
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 792e8cc4a518..9c9eeb79b40a 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -62,7 +62,13 @@ namespace {
static QualType getType(APValue::LValueBase B) {
if (!B) return QualType();
if (const ValueDecl *D = B.dyn_cast<const ValueDecl*>())
- return D->getType();
+ // FIXME: It's unclear where we're supposed to take the type from, and
+ // this actually matters for arrays of unknown bound. Using the type of
+ // the most recent declaration isn't clearly correct in general. Eg:
+ //
+ // extern int arr[]; void f() { extern int arr[3]; };
+ // constexpr int *p = &arr[1]; // valid?
+ return cast<ValueDecl>(D->getMostRecentDecl())->getType();
const Expr *Base = B.get<const Expr*>();
@@ -141,6 +147,12 @@ namespace {
return E && E->getType()->isPointerType() && tryUnwrapAllocSizeCall(E);
}
+ /// The bound to claim that an array of unknown bound has.
+ /// The value in MostDerivedArraySize is undefined in this case. So, set it
+ /// to an arbitrary value that's likely to loudly break things if it's used.
+ static const uint64_t AssumedSizeForUnsizedArray =
+ std::numeric_limits<uint64_t>::max() / 2;
+
/// Determines if an LValue with the given LValueBase will have an unsized
/// array in its designator.
/// Find the path length and type of the most-derived subobject in the given
@@ -148,7 +160,8 @@ namespace {
static unsigned
findMostDerivedSubobject(ASTContext &Ctx, APValue::LValueBase Base,
ArrayRef<APValue::LValuePathEntry> Path,
- uint64_t &ArraySize, QualType &Type, bool &IsArray) {
+ uint64_t &ArraySize, QualType &Type, bool &IsArray,
+ bool &FirstEntryIsUnsizedArray) {
// This only accepts LValueBases from APValues, and APValues don't support
// arrays that lack size info.
assert(!isBaseAnAllocSizeCall(Base) &&
@@ -158,12 +171,18 @@ namespace {
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (Type->isArrayType()) {
- const ConstantArrayType *CAT =
- cast<ConstantArrayType>(Ctx.getAsArrayType(Type));
- Type = CAT->getElementType();
- ArraySize = CAT->getSize().getZExtValue();
+ const ArrayType *AT = Ctx.getAsArrayType(Type);
+ Type = AT->getElementType();
MostDerivedLength = I + 1;
IsArray = true;
+
+ if (auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
+ ArraySize = CAT->getSize().getZExtValue();
+ } else {
+ assert(I == 0 && "unexpected unsized array designator");
+ FirstEntryIsUnsizedArray = true;
+ ArraySize = AssumedSizeForUnsizedArray;
+ }
} else if (Type->isAnyComplexType()) {
const ComplexType *CT = Type->castAs<ComplexType>();
Type = CT->getElementType();
@@ -246,10 +265,12 @@ namespace {
Entries.insert(Entries.end(), VEntries.begin(), VEntries.end());
if (V.getLValueBase()) {
bool IsArray = false;
+ bool FirstIsUnsizedArray = false;
MostDerivedPathLength = findMostDerivedSubobject(
Ctx, V.getLValueBase(), V.getLValuePath(), MostDerivedArraySize,
- MostDerivedType, IsArray);
+ MostDerivedType, IsArray, FirstIsUnsizedArray);
MostDerivedIsArrayElement = IsArray;
+ FirstEntryIsAnUnsizedArray = FirstIsUnsizedArray;
}
}
}
@@ -318,7 +339,7 @@ namespace {
// The value in MostDerivedArraySize is undefined in this case. So, set it
// to an arbitrary value that's likely to loudly break things if it's
// used.
- MostDerivedArraySize = std::numeric_limits<uint64_t>::max() / 2;
+ MostDerivedArraySize = AssumedSizeForUnsizedArray;
MostDerivedPathLength = Entries.size();
}
/// Update this designator to refer to the given base or member of this
@@ -350,6 +371,7 @@ namespace {
MostDerivedArraySize = 2;
MostDerivedPathLength = Entries.size();
}
+ void diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info, const Expr *E);
void diagnosePointerArithmetic(EvalInfo &Info, const Expr *E,
const APSInt &N);
/// Add N to the address of this subobject.
@@ -357,6 +379,7 @@ namespace {
if (Invalid || !N) return;
uint64_t TruncatedN = N.extOrTrunc(64).getZExtValue();
if (isMostDerivedAnUnsizedArray()) {
+ diagnoseUnsizedArrayPointerArithmetic(Info, E);
// Can't verify -- trust that the user is doing the right thing (or if
// not, trust that the caller will catch the bad behavior).
// FIXME: Should we reject if this overflows, at least?
@@ -573,6 +596,31 @@ namespace {
/// declaration whose initializer is being evaluated, if any.
APValue *EvaluatingDeclValue;
+ /// EvaluatingObject - Pair of the AST node that an lvalue represents and
+ /// the call index that that lvalue was allocated in.
+ typedef std::pair<APValue::LValueBase, unsigned> EvaluatingObject;
+
+ /// EvaluatingConstructors - Set of objects that are currently being
+ /// constructed.
+ llvm::DenseSet<EvaluatingObject> EvaluatingConstructors;
+
+ struct EvaluatingConstructorRAII {
+ EvalInfo &EI;
+ EvaluatingObject Object;
+ bool DidInsert;
+ EvaluatingConstructorRAII(EvalInfo &EI, EvaluatingObject Object)
+ : EI(EI), Object(Object) {
+ DidInsert = EI.EvaluatingConstructors.insert(Object).second;
+ }
+ ~EvaluatingConstructorRAII() {
+ if (DidInsert) EI.EvaluatingConstructors.erase(Object);
+ }
+ };
+
+ bool isEvaluatingConstructor(APValue::LValueBase Decl, unsigned CallIndex) {
+ return EvaluatingConstructors.count(EvaluatingObject(Decl, CallIndex));
+ }
+
/// The current array initialization index, if we're performing array
/// initialization.
uint64_t ArrayInitIndex = -1;
@@ -666,6 +714,7 @@ namespace {
void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) {
EvaluatingDecl = Base;
EvaluatingDeclValue = &Value;
+ EvaluatingConstructors.insert({Base, 0});
}
const LangOptions &getLangOpts() const { return Ctx.getLangOpts(); }
@@ -984,6 +1033,7 @@ namespace {
void moveFromAndCancel(SpeculativeEvaluationRAII &&Other) {
Info = Other.Info;
OldStatus = Other.OldStatus;
+ OldIsSpeculativelyEvaluating = Other.OldIsSpeculativelyEvaluating;
Other.Info = nullptr;
}
@@ -1067,9 +1117,19 @@ bool SubobjectDesignator::checkSubobject(EvalInfo &Info, const Expr *E,
setInvalid();
return false;
}
+ // Note, we do not diagnose if isMostDerivedAnUnsizedArray(), because there
+ // must actually be at least one array element; even a VLA cannot have a
+ // bound of zero. And if our index is nonzero, we already had a CCEDiag.
return true;
}
+void SubobjectDesignator::diagnoseUnsizedArrayPointerArithmetic(EvalInfo &Info,
+ const Expr *E) {
+ Info.CCEDiag(E, diag::note_constexpr_unsized_array_indexed);
+ // Do not set the designator as invalid: we can represent this situation,
+ // and correct handling of __builtin_object_size requires us to do so.
+}
+
void SubobjectDesignator::diagnosePointerArithmetic(EvalInfo &Info,
const Expr *E,
const APSInt &N) {
@@ -1213,8 +1273,6 @@ namespace {
IsNullPtr);
else {
assert(!InvalidBase && "APValues can't handle invalid LValue bases");
- assert(!Designator.FirstEntryIsAnUnsizedArray &&
- "Unsized array with a valid base?");
V = APValue(Base, Offset, Designator.Entries,
Designator.IsOnePastTheEnd, CallIndex, IsNullPtr);
}
@@ -1287,12 +1345,17 @@ namespace {
if (checkSubobject(Info, E, isa<FieldDecl>(D) ? CSK_Field : CSK_Base))
Designator.addDeclUnchecked(D, Virtual);
}
- void addUnsizedArray(EvalInfo &Info, QualType ElemTy) {
- assert(Designator.Entries.empty() && getType(Base)->isPointerType());
- assert(isBaseAnAllocSizeCall(Base) &&
- "Only alloc_size bases can have unsized arrays");
- Designator.FirstEntryIsAnUnsizedArray = true;
- Designator.addUnsizedArrayUnchecked(ElemTy);
+ void addUnsizedArray(EvalInfo &Info, const Expr *E, QualType ElemTy) {
+ if (!Designator.Entries.empty()) {
+ Info.CCEDiag(E, diag::note_constexpr_unsupported_unsized_array);
+ Designator.setInvalid();
+ return;
+ }
+ if (checkSubobject(Info, E, CSK_ArrayToPointer)) {
+ assert(getType(Base)->isPointerType() || getType(Base)->isArrayType());
+ Designator.FirstEntryIsAnUnsizedArray = true;
+ Designator.addUnsizedArrayUnchecked(ElemTy);
+ }
}
void addArray(EvalInfo &Info, const Expr *E, const ConstantArrayType *CAT) {
if (checkSubobject(Info, E, CSK_ArrayToPointer))
@@ -1756,6 +1819,9 @@ static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
}
}
for (const auto *I : RD->fields()) {
+ if (I->isUnnamedBitfield())
+ continue;
+
if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
Value.getStructField(I->getFieldIndex())))
return false;
@@ -2597,10 +2663,12 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
if (Sub.Invalid)
// A diagnostic will have already been produced.
return handler.failed();
- if (Sub.isOnePastTheEnd()) {
+ if (Sub.isOnePastTheEnd() || Sub.isMostDerivedAnUnsizedArray()) {
if (Info.getLangOpts().CPlusPlus11)
- Info.FFDiag(E, diag::note_constexpr_access_past_end)
- << handler.AccessKind;
+ Info.FFDiag(E, Sub.isOnePastTheEnd()
+ ? diag::note_constexpr_access_past_end
+ : diag::note_constexpr_access_unsized_array)
+ << handler.AccessKind;
else
Info.FFDiag(E);
return handler.failed();
@@ -3097,10 +3165,9 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
}
// During the construction of an object, it is not yet 'const'.
- // FIXME: We don't set up EvaluatingDecl for local variables or temporaries,
- // and this doesn't do quite the right thing for const subobjects of the
+ // FIXME: This doesn't do quite the right thing for const subobjects of the
// object under construction.
- if (LVal.getLValueBase() == Info.EvaluatingDecl) {
+ if (Info.isEvaluatingConstructor(LVal.getLValueBase(), LVal.CallIndex)) {
BaseType = Info.Ctx.getCanonicalType(BaseType);
BaseType.removeLocalConst();
}
@@ -4253,6 +4320,8 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
return false;
}
+ EvalInfo::EvaluatingConstructorRAII EvalObj(
+ Info, {This.getLValueBase(), This.CallIndex});
CallStackFrame Frame(Info, CallLoc, Definition, &This, ArgValues);
// FIXME: Creating an APValue just to hold a nonexistent return value is
@@ -5459,7 +5528,7 @@ static bool evaluateLValueAsAllocSize(EvalInfo &Info, APValue::LValueBase Base,
Result.setInvalid(E);
QualType Pointee = E->getType()->castAs<PointerType>()->getPointeeType();
- Result.addUnsizedArray(Info, Pointee);
+ Result.addUnsizedArray(Info, E, Pointee);
return true;
}
@@ -5669,7 +5738,8 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
return true;
}
}
- case CK_ArrayToPointerDecay:
+
+ case CK_ArrayToPointerDecay: {
if (SubExpr->isGLValue()) {
if (!evaluateLValue(SubExpr, Result))
return false;
@@ -5680,12 +5750,13 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
return false;
}
// The result is a pointer to the first element of the array.
- if (const ConstantArrayType *CAT
- = Info.Ctx.getAsConstantArrayType(SubExpr->getType()))
+ auto *AT = Info.Ctx.getAsArrayType(SubExpr->getType());
+ if (auto *CAT = dyn_cast<ConstantArrayType>(AT))
Result.addArray(Info, E, CAT);
else
- Result.Designator.setInvalid();
+ Result.addUnsizedArray(Info, E, AT->getElementType());
return true;
+ }
case CK_FunctionToPointerDecay:
return evaluateLValue(SubExpr, Result);
@@ -5752,7 +5823,7 @@ bool PointerExprEvaluator::visitNonBuiltinCallExpr(const CallExpr *E) {
Result.setInvalid(E);
QualType PointeeTy = E->getType()->castAs<PointerType>()->getPointeeType();
- Result.addUnsizedArray(Info, PointeeTy);
+ Result.addUnsizedArray(Info, E, PointeeTy);
return true;
}
@@ -7313,7 +7384,8 @@ static const Expr *ignorePointerCastsAndParens(const Expr *E) {
/// Please note: this function is specialized for how __builtin_object_size
/// views "objects".
///
-/// If this encounters an invalid RecordDecl, it will always return true.
+/// If this encounters an invalid RecordDecl or otherwise cannot determine the
+/// correct result, it will always return true.
static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) {
assert(!LVal.Designator.Invalid);
@@ -7344,9 +7416,8 @@ static bool isDesignatorAtObjectEnd(const ASTContext &Ctx, const LValue &LVal) {
unsigned I = 0;
QualType BaseType = getType(Base);
if (LVal.Designator.FirstEntryIsAnUnsizedArray) {
- assert(isBaseAnAllocSizeCall(Base) &&
- "Unsized array in non-alloc_size call?");
- // If this is an alloc_size base, we should ignore the initial array index
+ // If we don't know the array bound, conservatively assume we're looking at
+ // the final array element.
++I;
BaseType = BaseType->castAs<PointerType>()->getPointeeType();
}
@@ -7901,6 +7972,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return BuiltinOp == Builtin::BI__atomic_always_lock_free ?
Success(0, E) : Error(E);
}
+ case Builtin::BIomp_is_initial_device:
+ // We can decide statically which value the runtime would return if called.
+ return Success(Info.getLangOpts().OpenMPIsDevice ? 0 : 1, E);
}
}
@@ -10397,6 +10471,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
case BO_AndAssign:
case BO_XorAssign:
case BO_OrAssign:
+ case BO_Cmp: // FIXME: Re-enable once we can evaluate this.
// C99 6.6/3 allows assignments within unevaluated subexpressions of
// constant expressions, but they can never be ICEs because an ICE cannot
// contain an lvalue operand.
diff --git a/lib/AST/ExprObjC.cpp b/lib/AST/ExprObjC.cpp
index 31c1b3f15621..e1a23f598589 100644
--- a/lib/AST/ExprObjC.cpp
+++ b/lib/AST/ExprObjC.cpp
@@ -1,4 +1,4 @@
-//===--- ExprObjC.cpp - (ObjC) Expression AST Node Implementation ---------===//
+//===- ExprObjC.cpp - (ObjC) Expression AST Node Implementation -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,15 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ExprObjC.h"
-
#include "clang/AST/ASTContext.h"
+#include "clang/AST/SelectorLocationsKind.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
using namespace clang;
@@ -45,7 +52,6 @@ ObjCArrayLiteral *ObjCArrayLiteral::Create(const ASTContext &C,
ObjCArrayLiteral *ObjCArrayLiteral::CreateEmpty(const ASTContext &C,
unsigned NumElements) {
-
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumElements));
return new (Mem) ObjCArrayLiteral(EmptyShell(), NumElements);
}
diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp
index 4f4a99794c5b..6b75c51c6420 100644
--- a/lib/AST/ExternalASTMerger.cpp
+++ b/lib/AST/ExternalASTMerger.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/ExternalASTMerger.h"
@@ -32,26 +33,18 @@ template <typename T> struct Source {
typedef std::pair<Source<NamedDecl *>, ASTImporter *> Candidate;
-class LazyASTImporter : public ASTImporter {
-public:
- LazyASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
- ASTContext &FromContext, FileManager &FromFileManager)
- : ASTImporter(ToContext, ToFileManager, FromContext, FromFileManager,
- /*MinimalImport=*/true) {}
- Decl *Imported(Decl *From, Decl *To) override {
- if (auto ToTag = dyn_cast<TagDecl>(To)) {
- ToTag->setHasExternalLexicalStorage();
- ToTag->setMustBuildLookupTable();
- } else if (auto ToNamespace = dyn_cast<NamespaceDecl>(To)) {
- ToNamespace->setHasExternalVisibleStorage();
- }
- return ASTImporter::Imported(From, To);
- }
-};
+/// For the given DC, return the DC that is safe to perform lookups on. This is
+/// the DC we actually want to work with most of the time.
+const DeclContext *CanonicalizeDC(const DeclContext *DC) {
+ if (isa<LinkageSpecDecl>(DC))
+ return DC->getRedeclContext();
+ return DC;
+}
Source<const DeclContext *>
LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
ASTImporter &ReverseImporter) {
+ DC = CanonicalizeDC(DC);
if (DC->isTranslationUnit()) {
return SourceTU;
}
@@ -61,100 +54,328 @@ LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
// If we couldn't find the parent DC in this TranslationUnit, give up.
return nullptr;
}
- auto ND = cast<NamedDecl>(DC);
+ auto *ND = cast<NamedDecl>(DC);
DeclarationName Name = ND->getDeclName();
Source<DeclarationName> SourceName = ReverseImporter.Import(Name);
DeclContext::lookup_result SearchResult =
SourceParentDC.get()->lookup(SourceName.get());
size_t SearchResultSize = SearchResult.size();
- // Handle multiple candidates once we have a test for it.
- // This may turn up when we import template specializations correctly.
- assert(SearchResultSize < 2);
- if (SearchResultSize == 0) {
- // couldn't find the name, so we have to give up
+ if (SearchResultSize == 0 || SearchResultSize > 1) {
+ // There are two cases here. First, we might not find the name.
+ // We might also find multiple copies, in which case we have no
+ // guarantee that the one we wanted is the one we pick. (E.g.,
+ // if we have two specializations of the same template it is
+ // very hard to determine which is the one you want.)
+ //
+ // The Origins map fixes this problem by allowing the origin to be
+ // explicitly recorded, so we trigger that recording by returning
+ // nothing (rather than a possibly-inaccurate guess) here.
return nullptr;
} else {
NamedDecl *SearchResultDecl = SearchResult[0];
- return dyn_cast<DeclContext>(SearchResultDecl);
+ if (isa<DeclContext>(SearchResultDecl) &&
+ SearchResultDecl->getKind() == DC->getDeclKind())
+ return cast<DeclContext>(SearchResultDecl)->getPrimaryContext();
+ return nullptr; // This type of lookup is unsupported
}
}
-bool IsForwardDeclaration(Decl *D) {
- assert(!isa<ObjCInterfaceDecl>(D)); // TODO handle this case
- if (auto TD = dyn_cast<TagDecl>(D)) {
- return !TD->isThisDeclarationADefinition();
- } else if (auto FD = dyn_cast<FunctionDecl>(D)) {
- return !FD->isThisDeclarationADefinition();
- } else {
- return false;
- }
-}
+/// A custom implementation of ASTImporter, for ExternalASTMerger's purposes.
+///
+/// There are several modifications:
+///
+/// - It enables lazy lookup (via the HasExternalLexicalStorage flag and a few
+/// others), which instructs Clang to refer to ExternalASTMerger. Also, it
+/// forces MinimalImport to true, which is necessary to make this work.
+/// - It maintains a reverse importer for use with names. This allows lookup of
+/// arbitrary names in the source context.
+/// - It updates the ExternalASTMerger's origin map as needed whenever a
+/// it sees a DeclContext.
+class LazyASTImporter : public ASTImporter {
+private:
+ ExternalASTMerger &Parent;
+ ASTImporter Reverse;
+ const ExternalASTMerger::OriginMap &FromOrigins;
-template <typename CallbackType>
-void ForEachMatchingDC(
- const DeclContext *DC,
- llvm::ArrayRef<ExternalASTMerger::ImporterPair> Importers,
- CallbackType Callback) {
- for (const ExternalASTMerger::ImporterPair &IP : Importers) {
- Source<TranslationUnitDecl *> SourceTU =
- IP.Forward->getFromContext().getTranslationUnitDecl();
- if (auto SourceDC = LookupSameContext(SourceTU, DC, *IP.Reverse))
- Callback(IP, SourceDC);
+ llvm::raw_ostream &logs() { return Parent.logs(); }
+public:
+ LazyASTImporter(ExternalASTMerger &_Parent, ASTContext &ToContext,
+ FileManager &ToFileManager, ASTContext &FromContext,
+ FileManager &FromFileManager,
+ const ExternalASTMerger::OriginMap &_FromOrigins)
+ : ASTImporter(ToContext, ToFileManager, FromContext, FromFileManager,
+ /*MinimalImport=*/true),
+ Parent(_Parent), Reverse(FromContext, FromFileManager, ToContext,
+ ToFileManager, /*MinimalImport=*/true), FromOrigins(_FromOrigins) {}
+
+ /// Whenever a DeclContext is imported, ensure that ExternalASTSource's origin
+ /// map is kept up to date. Also set the appropriate flags.
+ Decl *Imported(Decl *From, Decl *To) override {
+ if (auto *ToDC = dyn_cast<DeclContext>(To)) {
+ const bool LoggingEnabled = Parent.LoggingEnabled();
+ if (LoggingEnabled)
+ logs() << "(ExternalASTMerger*)" << (void*)&Parent
+ << " imported (DeclContext*)" << (void*)ToDC
+ << ", (ASTContext*)" << (void*)&getToContext()
+ << " from (DeclContext*)" << (void*)llvm::cast<DeclContext>(From)
+ << ", (ASTContext*)" << (void*)&getFromContext()
+ << "\n";
+ Source<DeclContext *> FromDC(
+ cast<DeclContext>(From)->getPrimaryContext());
+ if (FromOrigins.count(FromDC) &&
+ Parent.HasImporterForOrigin(*FromOrigins.at(FromDC).AST)) {
+ if (LoggingEnabled)
+ logs() << "(ExternalASTMerger*)" << (void*)&Parent
+ << " forced origin (DeclContext*)"
+ << (void*)FromOrigins.at(FromDC).DC
+ << ", (ASTContext*)"
+ << (void*)FromOrigins.at(FromDC).AST
+ << "\n";
+ Parent.ForceRecordOrigin(ToDC, FromOrigins.at(FromDC));
+ } else {
+ if (LoggingEnabled)
+ logs() << "(ExternalASTMerger*)" << (void*)&Parent
+ << " maybe recording origin (DeclContext*)" << (void*)FromDC
+ << ", (ASTContext*)" << (void*)&getFromContext()
+ << "\n";
+ Parent.MaybeRecordOrigin(ToDC, {FromDC, &getFromContext()});
+ }
+ }
+ if (auto *ToTag = dyn_cast<TagDecl>(To)) {
+ ToTag->setHasExternalLexicalStorage();
+ ToTag->setMustBuildLookupTable();
+ assert(Parent.CanComplete(ToTag));
+ } else if (auto *ToNamespace = dyn_cast<NamespaceDecl>(To)) {
+ ToNamespace->setHasExternalVisibleStorage();
+ assert(Parent.CanComplete(ToNamespace));
+ } else if (auto *ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
+ ToContainer->setHasExternalLexicalStorage();
+ ToContainer->setMustBuildLookupTable();
+ assert(Parent.CanComplete(ToContainer));
+ }
+ return ASTImporter::Imported(From, To);
}
-}
+ ASTImporter &GetReverse() { return Reverse; }
+};
bool HasDeclOfSameType(llvm::ArrayRef<Candidate> Decls, const Candidate &C) {
+ if (isa<FunctionDecl>(C.first.get()))
+ return false;
return llvm::any_of(Decls, [&](const Candidate &D) {
return C.first.get()->getKind() == D.first.get()->getKind();
});
}
+
} // end namespace
-ExternalASTMerger::ExternalASTMerger(const ImporterEndpoint &Target,
- llvm::ArrayRef<ImporterEndpoint> Sources) {
- for (const ImporterEndpoint &S : Sources) {
- Importers.push_back(
- {llvm::make_unique<LazyASTImporter>(Target.AST, Target.FM, S.AST, S.FM),
- llvm::make_unique<ASTImporter>(S.AST, S.FM, Target.AST, Target.FM,
- /*MinimalImport=*/true)});
- }
+ASTImporter &ExternalASTMerger::ImporterForOrigin(ASTContext &OriginContext) {
+ for (const std::unique_ptr<ASTImporter> &I : Importers)
+ if (&I->getFromContext() == &OriginContext)
+ return *I;
+ llvm_unreachable("We should have an importer for this origin!");
}
-bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
- DeclarationName Name) {
- llvm::SmallVector<NamedDecl *, 1> Decls;
- llvm::SmallVector<Candidate, 4> CompleteDecls;
- llvm::SmallVector<Candidate, 4> ForwardDecls;
+namespace {
+LazyASTImporter &LazyImporterForOrigin(ExternalASTMerger &Merger,
+ ASTContext &OriginContext) {
+ return static_cast<LazyASTImporter &>(
+ Merger.ImporterForOrigin(OriginContext));
+}
+}
- auto FilterFoundDecl = [&CompleteDecls, &ForwardDecls](const Candidate &C) {
- if (IsForwardDeclaration(C.first.get())) {
- if (!HasDeclOfSameType(ForwardDecls, C)) {
- ForwardDecls.push_back(C);
+bool ExternalASTMerger::HasImporterForOrigin(ASTContext &OriginContext) {
+ for (const std::unique_ptr<ASTImporter> &I : Importers)
+ if (&I->getFromContext() == &OriginContext)
+ return true;
+ return false;
+}
+
+template <typename CallbackType>
+void ExternalASTMerger::ForEachMatchingDC(const DeclContext *DC,
+ CallbackType Callback) {
+ if (Origins.count(DC)) {
+ ExternalASTMerger::DCOrigin Origin = Origins[DC];
+ LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
+ Callback(Importer, Importer.GetReverse(), Origin.DC);
+ } else {
+ bool DidCallback = false;
+ for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
+ Source<TranslationUnitDecl *> SourceTU =
+ Importer->getFromContext().getTranslationUnitDecl();
+ ASTImporter &Reverse =
+ static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
+ if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
+ DidCallback = true;
+ if (Callback(*Importer, Reverse, SourceDC))
+ break;
}
- } else {
- CompleteDecls.push_back(C);
}
- };
+ if (!DidCallback && LoggingEnabled())
+ logs() << "(ExternalASTMerger*)" << (void*)this
+ << " asserting for (DeclContext*)" << (const void*)DC
+ << ", (ASTContext*)" << (void*)&Target.AST
+ << "\n";
+ assert(DidCallback && "Couldn't find a source context matching our DC");
+ }
+}
+
+void ExternalASTMerger::CompleteType(TagDecl *Tag) {
+ assert(Tag->hasExternalLexicalStorage());
+ ForEachMatchingDC(Tag, [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ auto *SourceTag = const_cast<TagDecl *>(cast<TagDecl>(SourceDC.get()));
+ if (SourceTag->hasExternalLexicalStorage())
+ SourceTag->getASTContext().getExternalSource()->CompleteType(SourceTag);
+ if (!SourceTag->getDefinition())
+ return false;
+ Forward.Imported(SourceTag, Tag);
+ Forward.ImportDefinition(SourceTag);
+ Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
+ return true;
+ });
+}
+void ExternalASTMerger::CompleteType(ObjCInterfaceDecl *Interface) {
+ assert(Interface->hasExternalLexicalStorage());
ForEachMatchingDC(
- DC, Importers,
- [&](const ImporterPair &IP, Source<const DeclContext *> SourceDC) {
- DeclarationName FromName = IP.Reverse->Import(Name);
- DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
- for (NamedDecl *FromD : Result) {
- FilterFoundDecl(std::make_pair(FromD, IP.Forward.get()));
- }
+ Interface, [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ auto *SourceInterface = const_cast<ObjCInterfaceDecl *>(
+ cast<ObjCInterfaceDecl>(SourceDC.get()));
+ if (SourceInterface->hasExternalLexicalStorage())
+ SourceInterface->getASTContext().getExternalSource()->CompleteType(
+ SourceInterface);
+ if (!SourceInterface->getDefinition())
+ return false;
+ Forward.Imported(SourceInterface, Interface);
+ Forward.ImportDefinition(SourceInterface);
+ return true;
});
+}
- llvm::ArrayRef<Candidate> DeclsToReport =
- CompleteDecls.empty() ? ForwardDecls : CompleteDecls;
+bool ExternalASTMerger::CanComplete(DeclContext *Interface) {
+ assert(Interface->hasExternalLexicalStorage() ||
+ Interface->hasExternalVisibleStorage());
+ bool FoundMatchingDC = false;
+ ForEachMatchingDC(Interface,
+ [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ FoundMatchingDC = true;
+ return true;
+ });
+ return FoundMatchingDC;
+}
- if (DeclsToReport.empty()) {
- return false;
+namespace {
+bool IsSameDC(const DeclContext *D1, const DeclContext *D2) {
+ if (isa<ObjCContainerDecl>(D1) && isa<ObjCContainerDecl>(D2))
+ return true; // There are many cases where Objective-C is ambiguous.
+ if (auto *T1 = dyn_cast<TagDecl>(D1))
+ if (auto *T2 = dyn_cast<TagDecl>(D2))
+ if (T1->getFirstDecl() == T2->getFirstDecl())
+ return true;
+ return D1 == D2 || D1 == CanonicalizeDC(D2);
+}
+}
+
+void ExternalASTMerger::MaybeRecordOrigin(const DeclContext *ToDC,
+ DCOrigin Origin) {
+ LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
+ ASTImporter &Reverse = Importer.GetReverse();
+ Source<const DeclContext *> FoundFromDC =
+ LookupSameContext(Origin.AST->getTranslationUnitDecl(), ToDC, Reverse);
+ const bool DoRecord = !FoundFromDC || !IsSameDC(FoundFromDC.get(), Origin.DC);
+ if (DoRecord)
+ RecordOriginImpl(ToDC, Origin, Importer);
+ if (LoggingEnabled())
+ logs() << "(ExternalASTMerger*)" << (void*)this
+ << (DoRecord ? " decided " : " decided NOT")
+ << " to record origin (DeclContext*)" << (void*)Origin.DC
+ << ", (ASTContext*)" << (void*)&Origin.AST
+ << "\n";
+}
+
+void ExternalASTMerger::ForceRecordOrigin(const DeclContext *ToDC,
+ DCOrigin Origin) {
+ RecordOriginImpl(ToDC, Origin, ImporterForOrigin(*Origin.AST));
+}
+
+void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
+ ASTImporter &Importer) {
+ Origins[ToDC] = Origin;
+ Importer.ASTImporter::Imported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
+}
+
+ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target,
+ llvm::ArrayRef<ImporterSource> Sources) : LogStream(&llvm::nulls()), Target(Target) {
+ AddSources(Sources);
+}
+
+void ExternalASTMerger::AddSources(llvm::ArrayRef<ImporterSource> Sources) {
+ for (const ImporterSource &S : Sources) {
+ assert(&S.AST != &Target.AST);
+ Importers.push_back(llvm::make_unique<LazyASTImporter>(
+ *this, Target.AST, Target.FM, S.AST, S.FM, S.OM));
+ }
+}
+
+void ExternalASTMerger::RemoveSources(llvm::ArrayRef<ImporterSource> Sources) {
+ if (LoggingEnabled())
+ for (const ImporterSource &S : Sources)
+ logs() << "(ExternalASTMerger*)" << (void*)this
+ << " removing source (ASTContext*)" << (void*)&S.AST
+ << "\n";
+ Importers.erase(
+ std::remove_if(Importers.begin(), Importers.end(),
+ [&Sources](std::unique_ptr<ASTImporter> &Importer) -> bool {
+ for (const ImporterSource &S : Sources) {
+ if (&Importer->getFromContext() == &S.AST)
+ return true;
+ }
+ return false;
+ }),
+ Importers.end());
+ for (OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
+ std::pair<const DeclContext *, DCOrigin> Origin = *OI;
+ bool Erase = false;
+ for (const ImporterSource &S : Sources) {
+ if (&S.AST == Origin.second.AST) {
+ Erase = true;
+ break;
+ }
+ }
+ if (Erase)
+ OI = Origins.erase(OI);
+ else
+ ++OI;
}
+}
+
+bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
+ DeclarationName Name) {
+ llvm::SmallVector<NamedDecl *, 1> Decls;
+ llvm::SmallVector<Candidate, 4> Candidates;
+
+ auto FilterFoundDecl = [&Candidates](const Candidate &C) {
+ if (!HasDeclOfSameType(Candidates, C))
+ Candidates.push_back(C);
+ };
+
+ ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ DeclarationName FromName = Reverse.Import(Name);
+ DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
+ for (NamedDecl *FromD : Result) {
+ FilterFoundDecl(std::make_pair(FromD, &Forward));
+ }
+ return false;
+ });
- Decls.reserve(DeclsToReport.size());
- for (const Candidate &C : DeclsToReport) {
+ if (Candidates.empty())
+ return false;
+
+ Decls.reserve(Candidates.size());
+ for (const Candidate &C : Candidates) {
NamedDecl *d = cast<NamedDecl>(C.second->Import(C.first.get()));
assert(d);
Decls.push_back(d);
@@ -166,17 +387,16 @@ bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
void ExternalASTMerger::FindExternalLexicalDecls(
const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) {
- ForEachMatchingDC(
- DC, Importers,
- [&](const ImporterPair &IP, Source<const DeclContext *> SourceDC) {
- for (const Decl *SourceDecl : SourceDC.get()->decls()) {
- if (IsKindWeWant(SourceDecl->getKind())) {
- Decl *ImportedDecl =
- IP.Forward->Import(const_cast<Decl *>(SourceDecl));
- assert(ImportedDecl->getDeclContext() == DC);
- (void)ImportedDecl;
- }
- }
- });
+ ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
+ Source<const DeclContext *> SourceDC) -> bool {
+ for (const Decl *SourceDecl : SourceDC.get()->decls()) {
+ if (IsKindWeWant(SourceDecl->getKind())) {
+ Decl *ImportedDecl = Forward.Import(const_cast<Decl *>(SourceDecl));
+ assert(!ImportedDecl || IsSameDC(ImportedDecl->getDeclContext(), DC));
+ (void)ImportedDecl;
+ }
+ }
+ return false;
+ });
}
diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp
index 182d38242f59..198ba9d4fbdb 100644
--- a/lib/AST/ExternalASTSource.cpp
+++ b/lib/AST/ExternalASTSource.cpp
@@ -1,4 +1,4 @@
-//===- ExternalASTSource.cpp - Abstract External AST Interface --*- C++ -*-===//
+//===- ExternalASTSource.cpp - Abstract External AST Interface ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,12 +16,16 @@
#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclarationName.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/Module.h"
+#include "llvm/ADT/None.h"
#include "llvm/Support/ErrorHandling.h"
+#include <cstdint>
using namespace clang;
-ExternalASTSource::~ExternalASTSource() { }
+ExternalASTSource::~ExternalASTSource() = default;
llvm::Optional<ExternalASTSource::ASTSourceDescriptor>
ExternalASTSource::getSourceDescriptor(unsigned ID) {
@@ -66,7 +70,7 @@ void ExternalASTSource::FinishedDeserializing() {}
void ExternalASTSource::StartTranslationUnit(ASTConsumer *Consumer) {}
-void ExternalASTSource::PrintStats() { }
+void ExternalASTSource::PrintStats() {}
bool ExternalASTSource::layoutRecordType(
const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
diff --git a/lib/AST/ItaniumCXXABI.cpp b/lib/AST/ItaniumCXXABI.cpp
index 692a455eafc0..d6bc16b6350f 100644
--- a/lib/AST/ItaniumCXXABI.cpp
+++ b/lib/AST/ItaniumCXXABI.cpp
@@ -101,15 +101,17 @@ protected:
public:
ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
- std::pair<uint64_t, unsigned>
- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override {
+ MemberPointerInfo
+ getMemberPointerInfo(const MemberPointerType *MPT) const override {
const TargetInfo &Target = Context.getTargetInfo();
TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
- uint64_t Width = Target.getTypeWidth(PtrDiff);
- unsigned Align = Target.getTypeAlign(PtrDiff);
+ MemberPointerInfo MPI;
+ MPI.Width = Target.getTypeWidth(PtrDiff);
+ MPI.Align = Target.getTypeAlign(PtrDiff);
+ MPI.HasPadding = false;
if (MPT->isMemberFunctionPointer())
- Width = 2 * Width;
- return std::make_pair(Width, Align);
+ MPI.Width *= 2;
+ return MPI;
}
CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 4e7c6c4edf37..f95dc8458e8a 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -11,7 +11,7 @@
// which is used in GCC 3.2 and newer (and many compilers that are
// ABI-compatible with GCC):
//
-// http://mentorembedded.github.io/cxx-abi/abi.html#mangling
+// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Mangle.h"
@@ -381,6 +381,7 @@ class CXXNameMangler {
AbiTagState AbiTagsRoot;
llvm::DenseMap<uintptr_t, unsigned> Substitutions;
+ llvm::DenseMap<StringRef, unsigned> ModuleSubstitutions;
ASTContext &getASTContext() const { return Context.getASTContext(); }
@@ -475,6 +476,8 @@ private:
void mangleNameWithAbiTags(const NamedDecl *ND,
const AbiTagList *AdditionalAbiTags);
+ void mangleModuleName(const Module *M);
+ void mangleModuleNamePrefix(StringRef Name);
void mangleTemplateName(const TemplateDecl *TD,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs);
@@ -517,7 +520,7 @@ private:
void mangleOperatorName(DeclarationName Name, unsigned Arity);
void mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity);
void mangleVendorQualifier(StringRef qualifier);
- void mangleQualifiers(Qualifiers Quals);
+ void mangleQualifiers(Qualifiers Quals, const DependentAddressSpaceType *DAST = nullptr);
void mangleRefQualifier(RefQualifierKind RefQualifier);
void mangleObjCMethodName(const ObjCMethodDecl *MD);
@@ -845,9 +848,9 @@ void CXXNameMangler::mangleName(const NamedDecl *ND) {
void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND,
const AbiTagList *AdditionalAbiTags) {
- // <name> ::= <nested-name>
- // ::= <unscoped-name>
- // ::= <unscoped-template-name> <template-args>
+ // <name> ::= [<module-name>] <nested-name>
+ // ::= [<module-name>] <unscoped-name>
+ // ::= [<module-name>] <unscoped-template-name> <template-args>
// ::= <local-name>
//
const DeclContext *DC = getEffectiveDeclContext(ND);
@@ -866,6 +869,19 @@ void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND,
DC = IgnoreLinkageSpecDecls(DC);
+ if (isLocalContainerContext(DC)) {
+ mangleLocalName(ND, AdditionalAbiTags);
+ return;
+ }
+
+ // Do not mangle the owning module for an external linkage declaration.
+ // This enables backwards-compatibility with non-modular code, and is
+ // a valid choice since conflicts are not permitted by C++ Modules TS
+ // [basic.def.odr]/6.2.
+ if (!ND->hasExternalFormalLinkage())
+ if (Module *M = ND->getOwningModuleForLinkage())
+ mangleModuleName(M);
+
if (DC->isTranslationUnit() || isStdNamespace(DC)) {
// Check if we have a template.
const TemplateArgumentList *TemplateArgs = nullptr;
@@ -879,12 +895,42 @@ void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND,
return;
}
- if (isLocalContainerContext(DC)) {
- mangleLocalName(ND, AdditionalAbiTags);
+ mangleNestedName(ND, DC, AdditionalAbiTags);
+}
+
+void CXXNameMangler::mangleModuleName(const Module *M) {
+ // Implement the C++ Modules TS name mangling proposal; see
+ // https://gcc.gnu.org/wiki/cxx-modules?action=AttachFile
+ //
+ // <module-name> ::= W <unscoped-name>+ E
+ // ::= W <module-subst> <unscoped-name>* E
+ Out << 'W';
+ mangleModuleNamePrefix(M->Name);
+ Out << 'E';
+}
+
+void CXXNameMangler::mangleModuleNamePrefix(StringRef Name) {
+ // <module-subst> ::= _ <seq-id> # 0 < seq-id < 10
+ // ::= W <seq-id - 10> _ # otherwise
+ auto It = ModuleSubstitutions.find(Name);
+ if (It != ModuleSubstitutions.end()) {
+ if (It->second < 10)
+ Out << '_' << static_cast<char>('0' + It->second);
+ else
+ Out << 'W' << (It->second - 10) << '_';
return;
}
- mangleNestedName(ND, DC, AdditionalAbiTags);
+ // FIXME: Preserve hierarchy in module names rather than flattening
+ // them to strings; use Module*s as substitution keys.
+ auto Parts = Name.rsplit('.');
+ if (Parts.second.empty())
+ Parts.second = Parts.first;
+ else
+ mangleModuleNamePrefix(Parts.first);
+
+ Out << Parts.second.size() << Parts.second;
+ ModuleSubstitutions.insert({Name, ModuleSubstitutions.size()});
}
void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD,
@@ -1233,14 +1279,23 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND,
}
if (II) {
- // We must avoid conflicts between internally- and externally-
- // linked variable and function declaration names in the same TU:
+ // Match GCC's naming convention for internal linkage symbols, for
+ // symbols that are not actually visible outside of this TU. GCC
+ // distinguishes between internal and external linkage symbols in
+ // its mangling, to support cases like this that were valid C++ prior
+ // to DR426:
+ //
// void test() { extern void foo(); }
// static void foo();
- // This naming convention is the same as that followed by GCC,
- // though it shouldn't actually matter.
+ //
+ // Don't bother with the L marker for names in anonymous namespaces; the
+ // 12_GLOBAL__N_1 mangling is quite sufficient there, and this better
+ // matches GCC anyway, because GCC does not treat anonymous namespaces as
+ // implying internal linkage.
if (ND && ND->getFormalLinkage() == InternalLinkage &&
- getEffectiveDeclContext(ND)->isFileContext())
+ !ND->isExternallyVisible() &&
+ getEffectiveDeclContext(ND)->isFileContext() &&
+ !ND->isInAnonymousNamespace())
Out << 'L';
auto *FD = dyn_cast<FunctionDecl>(ND);
@@ -1620,6 +1675,10 @@ void CXXNameMangler::mangleUnqualifiedBlock(const BlockDecl *Block) {
// the symbol in question isn't externally visible.
if (!Number)
Number = Context.getBlockId(Block, false);
+ else {
+ // Stored mangling numbers are 1-based.
+ --Number;
+ }
Out << "Ub";
if (Number > 0)
Out << Number - 1;
@@ -1638,10 +1697,15 @@ void CXXNameMangler::mangleLambda(const CXXRecordDecl *Lambda) {
// to emit that last part of the prefix here.
if (Decl *Context = Lambda->getLambdaContextDecl()) {
if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) &&
- Context->getDeclContext()->isRecord()) {
+ !isa<ParmVarDecl>(Context)) {
+ // FIXME: 'inline auto [a, b] = []{ return ... };' does not get a
+ // reasonable mangling here.
if (const IdentifierInfo *Name
= cast<NamedDecl>(Context)->getIdentifier()) {
mangleSourceName(Name);
+ const TemplateArgumentList *TemplateArgs = nullptr;
+ if (isTemplate(cast<NamedDecl>(Context), TemplateArgs))
+ mangleTemplateArgs(*TemplateArgs);
Out << 'M';
}
}
@@ -1866,6 +1930,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::IncompleteArray:
case Type::VariableArray:
case Type::DependentSizedArray:
+ case Type::DependentAddressSpace:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
@@ -2130,6 +2195,9 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
// Proposal on cxx-abi-dev, 2015-10-21.
// ::= aw # co_await
case OO_Coawait: Out << "aw"; break;
+ // Proposed in cxx-abi github issue 43.
+ // ::= ss # <=>
+ case OO_Spaceship: Out << "ss"; break;
case OO_None:
case NUM_OVERLOADED_OPERATORS:
@@ -2137,10 +2205,17 @@ CXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO, unsigned Arity) {
}
}
-void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
+void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSpaceType *DAST) {
// Vendor qualifiers come first and if they are order-insensitive they must
// be emitted in reversed alphabetical order, see Itanium ABI 5.1.5.
+ // <type> ::= U <addrspace-expr>
+ if (DAST) {
+ Out << "U2ASI";
+ mangleExpression(DAST->getAddrSpaceExpr());
+ Out << "E";
+ }
+
// Address space qualifiers start with an ordinary letter.
if (Quals.hasAddressSpace()) {
// Address space extension:
@@ -2150,20 +2225,22 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
// <type> ::= U <CUDA-addrspace>
SmallString<64> ASString;
- unsigned AS = Quals.getAddressSpace();
+ LangAS AS = Quals.getAddressSpace();
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
// <target-addrspace> ::= "AS" <address-space-number>
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
- ASString = "AS" + llvm::utostr(TargetAS);
+ if (TargetAS != 0)
+ ASString = "AS" + llvm::utostr(TargetAS);
} else {
switch (AS) {
default: llvm_unreachable("Not a language specific address space");
- // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant |
- // "generic" ]
+ // <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
+ // "private"| "generic" ]
case LangAS::opencl_global: ASString = "CLglobal"; break;
case LangAS::opencl_local: ASString = "CLlocal"; break;
case LangAS::opencl_constant: ASString = "CLconstant"; break;
+ case LangAS::opencl_private: ASString = "CLprivate"; break;
case LangAS::opencl_generic: ASString = "CLgeneric"; break;
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
case LangAS::cuda_device: ASString = "CUdevice"; break;
@@ -2171,7 +2248,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals) {
case LangAS::cuda_shared: ASString = "CUshared"; break;
}
}
- mangleVendorQualifier(ASString);
+ if (!ASString.empty())
+ mangleVendorQualifier(ASString);
}
// The ARC ownership qualifiers start with underscores.
@@ -2336,11 +2414,19 @@ void CXXNameMangler::mangleType(QualType T) {
// substitution at the original type.
}
- if (quals) {
- mangleQualifiers(quals);
- // Recurse: even if the qualified type isn't yet substitutable,
- // the unqualified type might be.
- mangleType(QualType(ty, 0));
+ if (quals || ty->isDependentAddressSpaceType()) {
+ if (const DependentAddressSpaceType *DAST =
+ dyn_cast<DependentAddressSpaceType>(ty)) {
+ SplitQualType splitDAST = DAST->getPointeeType().split();
+ mangleQualifiers(splitDAST.Quals, DAST);
+ mangleType(QualType(splitDAST.Ty, 0));
+ } else {
+ mangleQualifiers(quals);
+
+ // Recurse: even if the qualified type isn't yet substitutable,
+ // the unqualified type might be.
+ mangleType(QualType(ty, 0));
+ }
} else {
switch (ty->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, PARENT)
@@ -2392,6 +2478,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
// ::= Dh # IEEE 754r half-precision floating point (16 bits)
+ // ::= DF <number> _ # ISO/IEC TS 18661 binary floating point type _FloatN (N bits);
// ::= Di # char32_t
// ::= Ds # char16_t
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
@@ -2454,6 +2541,9 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Int128:
Out << 'n';
break;
+ case BuiltinType::Float16:
+ Out << "DF16_";
+ break;
case BuiltinType::Half:
Out << "Dh";
break;
@@ -2586,6 +2676,9 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) {
if (PI.isConsumed())
mangleVendorQualifier("ns_consumed");
+
+ if (PI.isNoEscape())
+ mangleVendorQualifier("noescape");
}
// <type> ::= <function-type>
@@ -2981,6 +3074,12 @@ void CXXNameMangler::mangleType(const DependentSizedExtVectorType *T) {
mangleType(T->getElementType());
}
+void CXXNameMangler::mangleType(const DependentAddressSpaceType *T) {
+ SplitQualType split = T->getPointeeType().split();
+ mangleQualifiers(split.Quals, T);
+ mangleType(QualType(split.Ty, 0));
+}
+
void CXXNameMangler::mangleType(const PackExpansionType *T) {
// <type> ::= Dp <type> # pack expansion (C++0x)
Out << "Dp";
@@ -3343,7 +3442,6 @@ recurse:
case Expr::BlockExprClass:
case Expr::ChooseExprClass:
case Expr::CompoundLiteralExprClass:
- case Expr::DesignatedInitExprClass:
case Expr::ExtVectorElementExprClass:
case Expr::GenericSelectionExprClass:
case Expr::ObjCEncodeExprClass:
@@ -3421,6 +3519,27 @@ recurse:
break;
}
+ case Expr::DesignatedInitExprClass: {
+ auto *DIE = cast<DesignatedInitExpr>(E);
+ for (const auto &Designator : DIE->designators()) {
+ if (Designator.isFieldDesignator()) {
+ Out << "di";
+ mangleSourceName(Designator.getFieldName());
+ } else if (Designator.isArrayDesignator()) {
+ Out << "dx";
+ mangleExpression(DIE->getArrayIndex(Designator));
+ } else {
+ assert(Designator.isArrayRangeDesignator() &&
+ "unknown designator kind");
+ Out << "dX";
+ mangleExpression(DIE->getArrayRangeStart(Designator));
+ mangleExpression(DIE->getArrayRangeEnd(Designator));
+ }
+ }
+ mangleExpression(DIE->getInit());
+ break;
+ }
+
case Expr::CXXDefaultArgExprClass:
mangleExpression(cast<CXXDefaultArgExpr>(E)->getExpr(), Arity);
break;
@@ -3512,7 +3631,6 @@ recurse:
if (const Expr *Base = PDE->getBase())
mangleMemberExprBase(Base, PDE->isArrow());
NestedNameSpecifier *Qualifier = PDE->getQualifier();
- QualType ScopeType;
if (TypeSourceInfo *ScopeInfo = PDE->getScopeTypeInfo()) {
if (Qualifier) {
mangleUnresolvedPrefix(Qualifier,
@@ -3578,6 +3696,16 @@ recurse:
const CXXUnresolvedConstructExpr *CE = cast<CXXUnresolvedConstructExpr>(E);
unsigned N = CE->arg_size();
+ if (CE->isListInitialization()) {
+ assert(N == 1 && "unexpected form for list initialization");
+ auto *IL = cast<InitListExpr>(CE->getArg(0));
+ Out << "tl";
+ mangleType(CE->getType());
+ mangleInitListElements(IL);
+ Out << "E";
+ return;
+ }
+
Out << "cv";
mangleType(CE->getType());
if (N != 1) Out << '_';
@@ -4114,7 +4242,13 @@ void CXXNameMangler::mangleFunctionParam(const ParmVarDecl *parm) {
// get mangled if used as an rvalue of a known non-class type?
assert(!parm->getType()->isArrayType()
&& "parameter's type is still an array type?");
- mangleQualifiers(parm->getType().getQualifiers());
+
+ if (const DependentAddressSpaceType *DAST =
+ dyn_cast<DependentAddressSpaceType>(parm->getType())) {
+ mangleQualifiers(DAST->getPointeeType().getQualifiers(), DAST);
+ } else {
+ mangleQualifiers(parm->getType().getQualifiers());
+ }
// Parameter index.
if (parmIndex != 0) {
diff --git a/lib/AST/Linkage.h b/lib/AST/Linkage.h
new file mode 100644
index 000000000000..e6489c7ef2b3
--- /dev/null
+++ b/lib/AST/Linkage.h
@@ -0,0 +1,159 @@
+//===----- Linkage.h - Linkage calculation-related utilities ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides AST-internal utilities for linkage and visibility
+// calculation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_AST_LINKAGE_H
+#define LLVM_CLANG_LIB_AST_LINKAGE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+/// Kinds of LV computation. The linkage side of the computation is
+/// always the same, but different things can change how visibility is
+/// computed.
+struct LVComputationKind {
+ /// The kind of entity whose visibility is ultimately being computed;
+ /// visibility computations for types and non-types follow different rules.
+ unsigned ExplicitKind : 1;
+ /// Whether explicit visibility attributes should be ignored. When set,
+ /// visibility may only be restricted by the visibility of template arguments.
+ unsigned IgnoreExplicitVisibility : 1;
+ /// Whether all visibility should be ignored. When set, we're only interested
+ /// in computing linkage.
+ unsigned IgnoreAllVisibility : 1;
+
+ explicit LVComputationKind(NamedDecl::ExplicitVisibilityKind EK)
+ : ExplicitKind(EK), IgnoreExplicitVisibility(false),
+ IgnoreAllVisibility(false) {}
+
+ NamedDecl::ExplicitVisibilityKind getExplicitVisibilityKind() const {
+ return static_cast<NamedDecl::ExplicitVisibilityKind>(ExplicitKind);
+ }
+
+ bool isTypeVisibility() const {
+ return getExplicitVisibilityKind() == NamedDecl::VisibilityForType;
+ }
+ bool isValueVisibility() const {
+ return getExplicitVisibilityKind() == NamedDecl::VisibilityForValue;
+ }
+
+ /// Do an LV computation when we only care about the linkage.
+ static LVComputationKind forLinkageOnly() {
+ LVComputationKind Result(NamedDecl::VisibilityForValue);
+ Result.IgnoreExplicitVisibility = true;
+ Result.IgnoreAllVisibility = true;
+ return Result;
+ }
+
+ unsigned toBits() {
+ unsigned Bits = 0;
+ Bits = (Bits << 1) | ExplicitKind;
+ Bits = (Bits << 1) | IgnoreExplicitVisibility;
+ Bits = (Bits << 1) | IgnoreAllVisibility;
+ return Bits;
+ }
+};
+
+class LinkageComputer {
+ // We have a cache for repeated linkage/visibility computations. This saves us
+ // from exponential behavior in heavily templated code, such as:
+ //
+ // template <typename T, typename V> struct {};
+ // using A = int;
+ // using B = Foo<A, A>;
+ // using C = Foo<B, B>;
+ // using D = Foo<C, C>;
+ //
+ // The unsigned represents an LVComputationKind.
+ using QueryType = std::pair<const NamedDecl *, unsigned>;
+ llvm::SmallDenseMap<QueryType, LinkageInfo, 8> CachedLinkageInfo;
+
+ static QueryType makeCacheKey(const NamedDecl *ND, LVComputationKind Kind) {
+ return std::make_pair(ND, Kind.toBits());
+ }
+
+ llvm::Optional<LinkageInfo> lookup(const NamedDecl *ND,
+ LVComputationKind Kind) const {
+ auto Iter = CachedLinkageInfo.find(makeCacheKey(ND, Kind));
+ if (Iter == CachedLinkageInfo.end())
+ return None;
+ return Iter->second;
+ }
+
+ void cache(const NamedDecl *ND, LVComputationKind Kind, LinkageInfo Info) {
+ CachedLinkageInfo[makeCacheKey(ND, Kind)] = Info;
+ }
+
+ LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+ LVComputationKind computation);
+
+ LinkageInfo getLVForTemplateArgumentList(const TemplateArgumentList &TArgs,
+ LVComputationKind computation);
+
+ void mergeTemplateLV(LinkageInfo &LV, const FunctionDecl *fn,
+ const FunctionTemplateSpecializationInfo *specInfo,
+ LVComputationKind computation);
+
+ void mergeTemplateLV(LinkageInfo &LV,
+ const ClassTemplateSpecializationDecl *spec,
+ LVComputationKind computation);
+
+ void mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation);
+
+ LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage);
+
+ LinkageInfo getLVForClassMember(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage);
+
+ LinkageInfo getLVForClosure(const DeclContext *DC, Decl *ContextDecl,
+ LVComputationKind computation);
+
+ LinkageInfo getLVForLocalDecl(const NamedDecl *D,
+ LVComputationKind computation);
+
+ LinkageInfo getLVForType(const Type &T, LVComputationKind computation);
+
+ LinkageInfo getLVForTemplateParameterList(const TemplateParameterList *Params,
+ LVComputationKind computation);
+
+public:
+ LinkageInfo computeLVForDecl(const NamedDecl *D,
+ LVComputationKind computation,
+ bool IgnoreVarTypeLinkage = false);
+
+ LinkageInfo getLVForDecl(const NamedDecl *D, LVComputationKind computation);
+
+ LinkageInfo computeTypeLinkageInfo(const Type *T);
+ LinkageInfo computeTypeLinkageInfo(QualType T) {
+ return computeTypeLinkageInfo(T.getTypePtr());
+ }
+
+ LinkageInfo getDeclLinkageAndVisibility(const NamedDecl *D);
+
+ LinkageInfo getTypeLinkageAndVisibility(const Type *T);
+ LinkageInfo getTypeLinkageAndVisibility(QualType T) {
+ return getTypeLinkageAndVisibility(T.getTypePtr());
+ }
+};
+} // namespace clang
+
+#endif
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 00d50c0e3bdf..56a2500274a7 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -103,6 +103,11 @@ bool MangleContext::shouldMangleDeclName(const NamedDecl *D) {
if (CC != CCM_Other)
return true;
+ // If the declaration has an owning module for linkage purposes that needs to
+ // be mangled, we must mangle its name.
+ if (!D->hasExternalFormalLinkage() && D->getOwningModuleForLinkage())
+ return true;
+
// In C, functions with no attributes never need to be mangled. Fastpath them.
if (!getASTContext().getLangOpts().CPlusPlus && !D->hasAttrs())
return false;
diff --git a/lib/AST/MicrosoftCXXABI.cpp b/lib/AST/MicrosoftCXXABI.cpp
index 73324e40f3b1..b19491f31304 100644
--- a/lib/AST/MicrosoftCXXABI.cpp
+++ b/lib/AST/MicrosoftCXXABI.cpp
@@ -76,8 +76,8 @@ class MicrosoftCXXABI : public CXXABI {
public:
MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
- std::pair<uint64_t, unsigned>
- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
+ MemberPointerInfo
+ getMemberPointerInfo(const MemberPointerType *MPT) const override;
CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
if (!isVariadic &&
@@ -227,7 +227,7 @@ getMSMemberPointerSlots(const MemberPointerType *MPT) {
return std::make_pair(Ptrs, Ints);
}
-std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
+CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
const MemberPointerType *MPT) const {
// The nominal struct is laid out with pointers followed by ints and aligned
// to a pointer width if any are present and an int width otherwise.
@@ -237,22 +237,25 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
unsigned Ptrs, Ints;
std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
- uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
- unsigned Align;
+ MemberPointerInfo MPI;
+ MPI.HasPadding = false;
+ MPI.Width = Ptrs * PtrSize + Ints * IntSize;
// When MSVC does x86_32 record layout, it aligns aggregate member pointers to
// 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
// function memptrs.
if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
- Align = 64;
+ MPI.Align = 64;
else if (Ptrs)
- Align = Target.getPointerAlign(0);
+ MPI.Align = Target.getPointerAlign(0);
else
- Align = Target.getIntAlign();
+ MPI.Align = Target.getIntAlign();
- if (Target.getTriple().isArch64Bit())
- Width = llvm::alignTo(Width, Align);
- return std::make_pair(Width, Align);
+ if (Target.getTriple().isArch64Bit()) {
+ MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
+ MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
+ }
+ return MPI;
}
CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 24b16f892e7a..0c55c1a92287 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -1192,6 +1192,15 @@ void MicrosoftCXXNameMangler::mangleOperatorName(OverloadedOperatorKind OO,
// <operator-name> ::= ?__L # co_await
case OO_Coawait: Out << "?__L"; break;
+ case OO_Spaceship: {
+ // FIXME: Once MS picks a mangling, use it.
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
+ "cannot mangle this three-way comparison operator yet");
+ Diags.Report(Loc, DiagID);
+ break;
+ }
+
case OO_Conditional: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
@@ -1866,6 +1875,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
Out << "$$T";
break;
+ case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half: {
DiagnosticsEngine &Diags = Context.getDiags();
@@ -2324,13 +2334,15 @@ void MicrosoftCXXNameMangler::mangleType(const PointerType *T, Qualifiers Quals,
manglePointerExtQualifiers(Quals, PointeeType);
mangleType(PointeeType, Range);
}
+
void MicrosoftCXXNameMangler::mangleType(const ObjCObjectPointerType *T,
Qualifiers Quals, SourceRange Range) {
+ if (T->isObjCIdType() || T->isObjCClassType())
+ return mangleType(T->getPointeeType(), Range, QMM_Drop);
+
QualType PointeeType = T->getPointeeType();
manglePointerCVQualifiers(Quals);
manglePointerExtQualifiers(Quals, PointeeType);
- // Object pointers never have qualifiers.
- Out << 'A';
mangleType(PointeeType, Range);
}
@@ -2427,6 +2439,15 @@ void MicrosoftCXXNameMangler::mangleType(const DependentSizedExtVectorType *T,
<< Range;
}
+void MicrosoftCXXNameMangler::mangleType(const DependentAddressSpaceType *T,
+ Qualifiers, SourceRange Range) {
+ DiagnosticsEngine &Diags = Context.getDiags();
+ unsigned DiagID = Diags.getCustomDiagID(
+ DiagnosticsEngine::Error,
+ "cannot mangle this dependent address space type yet");
+ Diags.Report(Range.getBegin(), DiagID) << Range;
+}
+
void MicrosoftCXXNameMangler::mangleType(const ObjCInterfaceType *T, Qualifiers,
SourceRange) {
// ObjC interfaces have structs underlying them.
@@ -2438,7 +2459,7 @@ void MicrosoftCXXNameMangler::mangleType(const ObjCObjectType *T, Qualifiers,
SourceRange Range) {
// We don't allow overloading by different protocol qualification,
// so mangling them isn't necessary.
- mangleType(T->getBaseType(), Range);
+ mangleType(T->getBaseType(), Range, QMM_Drop);
}
void MicrosoftCXXNameMangler::mangleType(const BlockPointerType *T,
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index e7c8c16b0145..8adaef1fb640 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -441,6 +441,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::Int128:
case BuiltinType::LongDouble:
case BuiltinType::UInt128:
+ case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::NullPtr:
case BuiltinType::ObjCClass:
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index e2e0dbeec0dd..889f8308a93c 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -1,4 +1,4 @@
-//===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
+//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,16 +11,28 @@
// a C++ nested-name-specifier.
//
//===----------------------------------------------------------------------===//
+
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
-#include "llvm/Support/AlignOf.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
#include <cassert>
+#include <cstdlib>
+#include <cstring>
using namespace clang;
@@ -314,8 +326,8 @@ NestedNameSpecifier::print(raw_ostream &OS,
SpecType->getTemplateName().print(OS, InnerPolicy, true);
// Print the template argument list.
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, SpecType->template_arguments(), InnerPolicy);
+ printTemplateArgumentList(OS, SpecType->template_arguments(),
+ InnerPolicy);
} else {
// Print the type normally
QualType(T, 0).print(OS, InnerPolicy);
@@ -375,22 +387,20 @@ NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
return Length;
}
-namespace {
- /// \brief Load a (possibly unaligned) source location from a given address
- /// and offset.
- SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
- unsigned Raw;
- memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
- return SourceLocation::getFromRawEncoding(Raw);
- }
+/// \brief Load a (possibly unaligned) source location from a given address
+/// and offset.
+static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
+ unsigned Raw;
+ memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(unsigned));
+ return SourceLocation::getFromRawEncoding(Raw);
+}
- /// \brief Load a (possibly unaligned) pointer from a given address and
- /// offset.
- void *LoadPointer(void *Data, unsigned Offset) {
- void *Result;
- memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
- return Result;
- }
+/// \brief Load a (possibly unaligned) pointer from a given address and
+/// offset.
+static void *LoadPointer(void *Data, unsigned Offset) {
+ void *Result;
+ memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
+ return Result;
}
SourceRange NestedNameSpecifierLoc::getSourceRange() const {
@@ -446,53 +456,49 @@ TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
return TypeLoc(Qualifier->getAsType(), TypeData);
}
-namespace {
- void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
+static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
unsigned &BufferCapacity) {
- if (Start == End)
- return;
+ if (Start == End)
+ return;
- if (BufferSize + (End - Start) > BufferCapacity) {
- // Reallocate the buffer.
- unsigned NewCapacity = std::max(
- (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
- (unsigned)(BufferSize + (End - Start)));
- char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
- if (BufferCapacity) {
- memcpy(NewBuffer, Buffer, BufferSize);
- free(Buffer);
- }
- Buffer = NewBuffer;
- BufferCapacity = NewCapacity;
+ if (BufferSize + (End - Start) > BufferCapacity) {
+ // Reallocate the buffer.
+ unsigned NewCapacity = std::max(
+ (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
+ (unsigned)(BufferSize + (End - Start)));
+ char *NewBuffer = static_cast<char *>(malloc(NewCapacity));
+ if (BufferCapacity) {
+ memcpy(NewBuffer, Buffer, BufferSize);
+ free(Buffer);
}
-
- memcpy(Buffer + BufferSize, Start, End - Start);
- BufferSize += End-Start;
+ Buffer = NewBuffer;
+ BufferCapacity = NewCapacity;
}
+
+ memcpy(Buffer + BufferSize, Start, End - Start);
+ BufferSize += End-Start;
+}
- /// \brief Save a source location to the given buffer.
- void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
- unsigned &BufferSize, unsigned &BufferCapacity) {
- unsigned Raw = Loc.getRawEncoding();
- Append(reinterpret_cast<char *>(&Raw),
- reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
- Buffer, BufferSize, BufferCapacity);
- }
+/// \brief Save a source location to the given buffer.
+static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
+ unsigned &BufferSize, unsigned &BufferCapacity) {
+ unsigned Raw = Loc.getRawEncoding();
+ Append(reinterpret_cast<char *>(&Raw),
+ reinterpret_cast<char *>(&Raw) + sizeof(unsigned),
+ Buffer, BufferSize, BufferCapacity);
+}
- /// \brief Save a pointer to the given buffer.
- void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
- unsigned &BufferCapacity) {
- Append(reinterpret_cast<char *>(&Ptr),
- reinterpret_cast<char *>(&Ptr) + sizeof(void *),
- Buffer, BufferSize, BufferCapacity);
- }
+/// \brief Save a pointer to the given buffer.
+static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
+ unsigned &BufferCapacity) {
+ Append(reinterpret_cast<char *>(&Ptr),
+ reinterpret_cast<char *>(&Ptr) + sizeof(void *),
+ Buffer, BufferSize, BufferCapacity);
}
NestedNameSpecifierLocBuilder::
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
- : Representation(Other.Representation), Buffer(nullptr),
- BufferSize(0), BufferCapacity(0)
-{
+ : Representation(Other.Representation) {
if (!Other.Buffer)
return;
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp
index 121724a73152..17c95f2a0af7 100644
--- a/lib/AST/ODRHash.cpp
+++ b/lib/AST/ODRHash.cpp
@@ -158,7 +158,14 @@ void ODRHash::AddTemplateArgument(TemplateArgument TA) {
}
}
-void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {}
+void ODRHash::AddTemplateParameterList(const TemplateParameterList *TPL) {
+ assert(TPL && "Expecting non-null pointer.");
+
+ ID.AddInteger(TPL->size());
+ for (auto *ND : TPL->asArray()) {
+ AddSubDecl(ND);
+ }
+}
void ODRHash::clear() {
DeclMap.clear();
@@ -199,6 +206,7 @@ unsigned ODRHash::CalculateHash() {
return ID.ComputeHash();
}
+namespace {
// Process a Decl pointer. Add* methods call back into ODRHash while Visit*
// methods process the relevant parts of the Decl.
class ODRDeclVisitor : public ConstDeclVisitor<ODRDeclVisitor> {
@@ -235,6 +243,10 @@ public:
}
}
+ void AddTemplateArgument(TemplateArgument TA) {
+ Hash.AddTemplateArgument(TA);
+ }
+
void Visit(const Decl *D) {
ID.AddInteger(D->getKind());
Inherited::Visit(D);
@@ -342,7 +354,44 @@ public:
AddDecl(D->getFriendDecl());
}
}
+
+ void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddTemplateArgument(D->getDefaultArgument());
+ }
+
+ Inherited::VisitTemplateTypeParmDecl(D);
+ }
+
+ void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddStmt(D->getDefaultArgument());
+ }
+
+ Inherited::VisitNonTypeTemplateParmDecl(D);
+ }
+
+ void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
+ // Only care about default arguments as part of the definition.
+ const bool hasDefaultArgument =
+ D->hasDefaultArgument() && !D->defaultArgumentWasInherited();
+ Hash.AddBoolean(hasDefaultArgument);
+ if (hasDefaultArgument) {
+ AddTemplateArgument(D->getDefaultArgument().getArgument());
+ }
+
+ Inherited::VisitTemplateTemplateParmDecl(D);
+ }
};
+} // namespace
// Only allow a small portion of Decl's to be processed. Remove this once
// all Decl's can be handled.
@@ -401,6 +450,20 @@ void ODRHash::AddCXXRecordDecl(const CXXRecordDecl *Record) {
for (auto SubDecl : Decls) {
AddSubDecl(SubDecl);
}
+
+ const ClassTemplateDecl *TD = Record->getDescribedClassTemplate();
+ AddBoolean(TD);
+ if (TD) {
+ AddTemplateParameterList(TD->getTemplateParameters());
+ }
+
+ ID.AddInteger(Record->getNumBases());
+ auto Bases = Record->bases();
+ for (auto Base : Bases) {
+ AddQualType(Base.getType());
+ ID.AddInteger(Base.isVirtual());
+ ID.AddInteger(Base.getAccessSpecifierAsWritten());
+ }
}
void ODRHash::AddDecl(const Decl *D) {
@@ -420,6 +483,7 @@ void ODRHash::AddDecl(const Decl *D) {
}
}
+namespace {
// Process a Type pointer. Add* methods call back into ODRHash while Visit*
// methods process the relevant parts of the Type.
class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
@@ -608,6 +672,7 @@ public:
AddDecl(T->getDecl());
}
};
+} // namespace
void ODRHash::AddType(const Type *T) {
assert(T && "Expecting non-null pointer.");
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index 2c4d159a1bc8..4feac0cfd041 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/lib/AST/OpenMPClause.cpp
@@ -1,4 +1,4 @@
-//===--- OpenMPClause.cpp - Classes for OpenMP clauses --------------------===//
+//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,14 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/OpenMPClause.h"
-
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
using namespace clang;
@@ -48,6 +54,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
return static_cast<const OMPReductionClause *>(C);
case OMPC_task_reduction:
return static_cast<const OMPTaskReductionClause *>(C);
+ case OMPC_in_reduction:
+ return static_cast<const OMPInReductionClause *>(C);
case OMPC_linear:
return static_cast<const OMPLinearClause *>(C);
case OMPC_if:
@@ -58,6 +66,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
return static_cast<const OMPNumTeamsClause *>(C);
case OMPC_thread_limit:
return static_cast<const OMPThreadLimitClause *>(C);
+ case OMPC_device:
+ return static_cast<const OMPDeviceClause *>(C);
case OMPC_default:
case OMPC_proc_bind:
case OMPC_final:
@@ -81,7 +91,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_capture:
case OMPC_seq_cst:
case OMPC_depend:
- case OMPC_device:
case OMPC_threads:
case OMPC_simd:
case OMPC_map:
@@ -116,6 +125,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
return static_cast<const OMPReductionClause *>(C);
case OMPC_task_reduction:
return static_cast<const OMPTaskReductionClause *>(C);
+ case OMPC_in_reduction:
+ return static_cast<const OMPInReductionClause *>(C);
case OMPC_linear:
return static_cast<const OMPLinearClause *>(C);
case OMPC_schedule:
@@ -562,6 +573,69 @@ OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPTaskReductionClause(N);
}
+void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
+ assert(Privates.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(Privates.begin(), Privates.end(), varlist_end());
+}
+
+void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
+ assert(
+ LHSExprs.size() == varlist_size() &&
+ "Number of LHS expressions is not the same as the preallocated buffer");
+ std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
+}
+
+void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
+ assert(
+ RHSExprs.size() == varlist_size() &&
+ "Number of RHS expressions is not the same as the preallocated buffer");
+ std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
+}
+
+void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
+ assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
+ "expressions is not the same "
+ "as the preallocated buffer");
+ std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
+}
+
+void OMPInReductionClause::setTaskgroupDescriptors(
+ ArrayRef<Expr *> TaskgroupDescriptors) {
+ assert(TaskgroupDescriptors.size() == varlist_size() &&
+ "Number of in reduction descriptors is not the same as the "
+ "preallocated buffer");
+ std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
+ getReductionOps().end());
+}
+
+OMPInReductionClause *OMPInReductionClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
+ ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
+ ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
+ ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
+ OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
+ StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+ Clause->setVarRefs(VL);
+ Clause->setPrivates(Privates);
+ Clause->setLHSExprs(LHSExprs);
+ Clause->setRHSExprs(RHSExprs);
+ Clause->setReductionOps(ReductionOps);
+ Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
+ Clause->setPreInitStmt(PreInit);
+ Clause->setPostUpdateExpr(PostUpdate);
+ return Clause;
+}
+
+OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
+ return new (Mem) OMPInReductionClause(N);
+}
+
OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
@@ -648,7 +722,6 @@ OMPMapClause::Create(const ASTContext &C, SourceLocation StartLoc,
MappableExprComponentListsRef ComponentLists,
OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type,
bool TypeIsImplicit, SourceLocation TypeLoc) {
-
unsigned NumVars = Vars.size();
unsigned NumUniqueDeclarations =
getUniqueDeclarationsTotalNumber(Declarations);
diff --git a/lib/Tooling/Core/QualTypeNames.cpp b/lib/AST/QualTypeNames.cpp
index 721c2c92fc27..86c0eff9f78c 100644
--- a/lib/Tooling/Core/QualTypeNames.cpp
+++ b/lib/AST/QualTypeNames.cpp
@@ -9,11 +9,11 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Tooling/Core/QualTypeNames.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/GlobalDecl.h"
#include "clang/AST/Mangle.h"
+#include "clang/AST/QualTypeNames.h"
#include <stdio.h>
#include <memory>
@@ -21,17 +21,6 @@
namespace clang {
namespace TypeName {
-/// \brief Generates a QualType that can be used to name the same type
-/// if used at the end of the current translation unit. This ignores
-/// issues such as type shadowing.
-///
-/// \param[in] QT - the type for which the fully qualified type will be
-/// returned.
-/// \param[in] Ctx - the ASTContext to be used.
-/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
-/// specifier "::" should be prepended or not.
-static QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
- bool WithGlobalNsPrefix);
/// \brief Create a NestedNameSpecifier for Namesp and its enclosing
/// scopes.
diff --git a/lib/AST/RecordLayout.cpp b/lib/AST/RecordLayout.cpp
index 299fd111bf6a..37fe029f53bd 100644
--- a/lib/AST/RecordLayout.cpp
+++ b/lib/AST/RecordLayout.cpp
@@ -1,4 +1,4 @@
-//===-- RecordLayout.cpp - Layout information for a struct/union -*- C++ -*-==//
+//===- RecordLayout.cpp - Layout information for a struct/union -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,9 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
+#include <cassert>
using namespace clang;
@@ -32,7 +34,7 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
CharUnits datasize,
ArrayRef<uint64_t> fieldoffsets)
: Size(size), DataSize(datasize), Alignment(alignment),
- RequiredAlignment(requiredAlignment), CXXInfo(nullptr) {
+ RequiredAlignment(requiredAlignment) {
FieldOffsets.append(Ctx, fieldoffsets.begin(), fieldoffsets.end());
}
@@ -73,7 +75,6 @@ ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
CXXInfo->EndsWithZeroSizedObject = EndsWithZeroSizedObject;
CXXInfo->LeadsWithZeroSizedBase = LeadsWithZeroSizedBase;
-
#ifndef NDEBUG
if (const CXXRecordDecl *PrimaryBase = getPrimaryBase()) {
if (isPrimaryBaseVirtual()) {
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index c0b9cadca422..a9d43dfa80c5 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -632,6 +632,9 @@ protected:
/// pointer, as opposed to inheriting one from a primary base class.
bool HasOwnVFPtr;
+ /// \brief the flag of field offset changing due to packed attribute.
+ bool HasPackedField;
+
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
/// Bases - base classes and their offsets in the record.
@@ -666,7 +669,7 @@ protected:
NonVirtualSize(CharUnits::Zero()),
NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr),
PrimaryBaseIsVirtual(false), HasOwnVFPtr(false),
- FirstNearlyEmptyVBase(nullptr) {}
+ HasPackedField(false), FirstNearlyEmptyVBase(nullptr) {}
void Layout(const RecordDecl *D);
void Layout(const CXXRecordDecl *D);
@@ -1166,7 +1169,6 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
// Query the external layout to see if it provides an offset.
bool HasExternalLayout = false;
if (UseExternalLayout) {
- llvm::DenseMap<const CXXRecordDecl *, CharUnits>::iterator Known;
if (Base->IsVirtual)
HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset);
else
@@ -1729,7 +1731,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
const ArrayType* ATy = Context.getAsArrayType(D->getType());
FieldAlign = Context.getTypeAlignInChars(ATy->getElementType());
} else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
- unsigned AS = RT->getPointeeType().getAddressSpace();
+ unsigned AS = Context.getTargetAddressSpace(RT->getPointeeType());
FieldSize =
Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(AS));
FieldAlign =
@@ -1847,7 +1849,6 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit;
uint64_t UnpackedSizeInBits =
llvm::alignTo(getSizeInBits(), Context.toBits(UnpackedAlignment));
- CharUnits UnpackedSize = Context.toCharUnitsFromBits(UnpackedSizeInBits);
uint64_t RoundedSize =
llvm::alignTo(getSizeInBits(), Context.toBits(Alignment));
@@ -1882,10 +1883,11 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
<< (InBits ? 1 : 0); // (byte|bit)
}
- // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
- // bother since there won't be alignment issues.
- if (Packed && UnpackedAlignment > CharUnits::One() &&
- getSize() == UnpackedSize)
+ // Warn if we packed it unnecessarily, when the unpacked alignment is not
+ // greater than the one after packing, the size in bits doesn't change and
+ // the offset of each field is identical.
+ if (Packed && UnpackedAlignment <= Alignment &&
+ UnpackedSizeInBits == getSizeInBits() && !HasPackedField)
Diag(D->getLocation(), diag::warn_unnecessary_packed)
<< Context.getTypeDeclType(RD);
}
@@ -1977,13 +1979,10 @@ void ItaniumRecordLayoutBuilder::CheckFieldPadding(
<< Context.getTypeDeclType(D->getParent())
<< PadSize
<< (InBits ? 1 : 0); // (byte|bit)
- }
-
- // Warn if we packed it unnecessarily. If the alignment is 1 byte don't
- // bother since there won't be alignment issues.
- if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset)
- Diag(D->getLocation(), diag::warn_unnecessary_packed)
- << D->getIdentifier();
+ }
+ if (isPacked && Offset != UnpackedOffset) {
+ HasPackedField = true;
+ }
}
static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
@@ -2084,7 +2083,7 @@ static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) {
// rules, we should implement the restrictions about over-sized
// bitfields:
//
- // http://mentorembedded.github.com/cxx-abi/abi.html#POD :
+ // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#POD :
// In general, a type is considered a POD for the purposes of
// layout if it is a POD type (in the sense of ISO C++
// [basic.types]). However, a POD-struct or POD-union (in the
@@ -2896,13 +2895,12 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
Work.insert(MD);
while (!Work.empty()) {
const CXXMethodDecl *MD = *Work.begin();
- CXXMethodDecl::method_iterator i = MD->begin_overridden_methods(),
- e = MD->end_overridden_methods();
+ auto MethodRange = MD->overridden_methods();
// If a virtual method has no-overrides it lives in its parent's vtable.
- if (i == e)
+ if (MethodRange.begin() == MethodRange.end())
BasesWithOverriddenMethods.insert(MD->getParent());
else
- Work.insert(i, e);
+ Work.insert(MethodRange.begin(), MethodRange.end());
// We've finished processing this element, remove it from the working set.
Work.erase(MD);
}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 2367cadf645c..8d240c1336ab 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1,4 +1,4 @@
-//===--- Stmt.cpp - Statement AST Node Implementation ---------------------===//
+//===- Stmt.cpp - Statement AST Node Implementation -----------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,6 +13,8 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclGroup.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
@@ -22,10 +24,24 @@
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Token.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+#include <string>
+#include <utility>
+
using namespace clang;
static struct StmtClassNameTable {
@@ -150,6 +166,7 @@ const Stmt *Stmt::stripLabelLikeStatements() const {
}
namespace {
+
struct good {};
struct bad {};
@@ -191,7 +208,8 @@ namespace {
(void) is_good(implements_getLocStart(&type::getLocStart))
#define ASSERT_IMPLEMENTS_getLocEnd(type) \
(void) is_good(implements_getLocEnd(&type::getLocEnd))
-}
+
+} // namespace
/// Check whether the various Stmt classes implement their member
/// functions.
@@ -222,6 +240,7 @@ Stmt::child_range Stmt::children() {
//
// See also Expr.cpp:getExprLoc().
namespace {
+
/// This implementation is used when a class provides a custom
/// implementation of getSourceRange.
template <class S, class T>
@@ -240,7 +259,8 @@ namespace {
return SourceRange(static_cast<const S*>(stmt)->getLocStart(),
static_cast<const S*>(stmt)->getLocEnd());
}
-}
+
+} // namespace
SourceRange Stmt::getSourceRange() const {
switch (getStmtClass()) {
@@ -286,7 +306,7 @@ CompoundStmt::CompoundStmt(const ASTContext &C, ArrayRef<Stmt*> Stmts,
assert(CompoundStmtBits.NumStmts == Stmts.size() &&
"NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!");
- if (Stmts.size() == 0) {
+ if (Stmts.empty()) {
Body = nullptr;
return;
}
@@ -408,6 +428,7 @@ StringRef GCCAsmStmt::getOutputConstraint(unsigned i) const {
Expr *GCCAsmStmt::getInputExpr(unsigned i) {
return cast<Expr>(Exprs[i + NumOutputs]);
}
+
void GCCAsmStmt::setInputExpr(unsigned i, Expr *E) {
Exprs[i + NumOutputs] = E;
}
@@ -506,7 +527,7 @@ unsigned GCCAsmStmt::AnalyzeAsmString(SmallVectorImpl<AsmStringPiece>&Pieces,
unsigned LastAsmStringToken = 0;
unsigned LastAsmStringOffset = 0;
- while (1) {
+ while (true) {
// Done with the string?
if (CurPtr == StrEnd) {
if (!CurStringPiece.empty())
@@ -682,6 +703,7 @@ Expr *MSAsmStmt::getOutputExpr(unsigned i) {
Expr *MSAsmStmt::getInputExpr(unsigned i) {
return cast<Expr>(Exprs[i + NumOutputs]);
}
+
void MSAsmStmt::setInputExpr(unsigned i, Expr *E) {
Exprs[i + NumOutputs] = E;
}
@@ -696,9 +718,8 @@ GCCAsmStmt::GCCAsmStmt(const ASTContext &C, SourceLocation asmloc,
StringLiteral **constraints, Expr **exprs,
StringLiteral *asmstr, unsigned numclobbers,
StringLiteral **clobbers, SourceLocation rparenloc)
- : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
- numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
-
+ : AsmStmt(GCCAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
+ numinputs, numclobbers), RParenLoc(rparenloc), AsmStr(asmstr) {
unsigned NumExprs = NumOutputs + NumInputs;
Names = new (C) IdentifierInfo*[NumExprs];
@@ -721,10 +742,9 @@ MSAsmStmt::MSAsmStmt(const ASTContext &C, SourceLocation asmloc,
ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs,
StringRef asmstr, ArrayRef<StringRef> clobbers,
SourceLocation endloc)
- : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
- numinputs, clobbers.size()), LBraceLoc(lbraceloc),
- EndLoc(endloc), NumAsmToks(asmtoks.size()) {
-
+ : AsmStmt(MSAsmStmtClass, asmloc, issimple, isvolatile, numoutputs,
+ numinputs, clobbers.size()), LBraceLoc(lbraceloc),
+ EndLoc(endloc), NumAsmToks(asmtoks.size()) {
initialize(C, asmstr, asmtoks, constraints, exprs, clobbers);
}
@@ -909,14 +929,9 @@ Expr* ReturnStmt::getRetValue() {
return cast_or_null<Expr>(RetExpr);
}
-SEHTryStmt::SEHTryStmt(bool IsCXXTry,
- SourceLocation TryLoc,
- Stmt *TryBlock,
+SEHTryStmt::SEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock,
Stmt *Handler)
- : Stmt(SEHTryStmtClass),
- IsCXXTry(IsCXXTry),
- TryLoc(TryLoc)
-{
+ : Stmt(SEHTryStmtClass), IsCXXTry(IsCXXTry), TryLoc(TryLoc) {
Children[TRY] = TryBlock;
Children[HANDLER] = Handler;
}
@@ -935,12 +950,8 @@ SEHFinallyStmt* SEHTryStmt::getFinallyHandler() const {
return dyn_cast<SEHFinallyStmt>(getHandler());
}
-SEHExceptStmt::SEHExceptStmt(SourceLocation Loc,
- Expr *FilterExpr,
- Stmt *Block)
- : Stmt(SEHExceptStmtClass),
- Loc(Loc)
-{
+SEHExceptStmt::SEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
+ : Stmt(SEHExceptStmtClass), Loc(Loc) {
Children[FILTER_EXPR] = FilterExpr;
Children[BLOCK] = Block;
}
@@ -950,12 +961,8 @@ SEHExceptStmt* SEHExceptStmt::Create(const ASTContext &C, SourceLocation Loc,
return new(C) SEHExceptStmt(Loc,FilterExpr,Block);
}
-SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc,
- Stmt *Block)
- : Stmt(SEHFinallyStmtClass),
- Loc(Loc),
- Block(Block)
-{}
+SEHFinallyStmt::SEHFinallyStmt(SourceLocation Loc, Stmt *Block)
+ : Stmt(SEHFinallyStmtClass), Loc(Loc), Block(Block) {}
SEHFinallyStmt* SEHFinallyStmt::Create(const ASTContext &C, SourceLocation Loc,
Stmt *Block) {
@@ -1037,7 +1044,7 @@ CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
: Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
- CapDeclAndKind(nullptr, CR_Default), TheRecordDecl(nullptr) {
+ CapDeclAndKind(nullptr, CR_Default) {
getStoredStmts()[NumCaptures] = nullptr;
}
@@ -1090,6 +1097,7 @@ Stmt::child_range CapturedStmt::children() {
CapturedDecl *CapturedStmt::getCapturedDecl() {
return CapDeclAndKind.getPointer();
}
+
const CapturedDecl *CapturedStmt::getCapturedDecl() const {
return CapDeclAndKind.getPointer();
}
@@ -1114,11 +1122,7 @@ bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
for (const auto &I : captures()) {
if (!I.capturesVariable() && !I.capturesVariableByCopy())
continue;
-
- // This does not handle variable redeclarations. This should be
- // extended to capture variables with redeclarations, for example
- // a thread-private variable in OpenMP.
- if (I.getCapturedVar() == Var)
+ if (I.getCapturedVar()->getCanonicalDecl() == Var->getCanonicalDecl())
return true;
}
diff --git a/lib/AST/StmtIterator.cpp b/lib/AST/StmtIterator.cpp
index 861d0908209d..00056e83af2c 100644
--- a/lib/AST/StmtIterator.cpp
+++ b/lib/AST/StmtIterator.cpp
@@ -1,4 +1,4 @@
-//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
+//===- StmtIterator.cpp - Iterators for Statements ------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,6 +13,11 @@
#include "clang/AST/StmtIterator.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstdint>
using namespace clang;
@@ -31,7 +36,7 @@ static inline const VariableArrayType *FindVA(const Type* t) {
}
void StmtIteratorBase::NextVA() {
- assert (getVAPtr());
+ assert(getVAPtr());
const VariableArrayType *p = getVAPtr();
p = FindVA(p->getElementType().getTypePtr());
@@ -93,22 +98,22 @@ bool StmtIteratorBase::HandleDecl(Decl* D) {
}
StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
- : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
+ : DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
NextDecl(false);
}
StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
- : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
+ : DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
RawVAPtr |= reinterpret_cast<uintptr_t>(t);
}
Stmt*& StmtIteratorBase::GetDeclExpr() const {
if (const VariableArrayType* VAPtr = getVAPtr()) {
- assert (VAPtr->SizeExpr);
+ assert(VAPtr->SizeExpr);
return const_cast<Stmt*&>(VAPtr->SizeExpr);
}
- assert (inDeclGroup());
+ assert(inDeclGroup());
VarDecl* VD = cast<VarDecl>(*DGI);
return *VD->getInitAddress();
}
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index 1dcb4fd5196b..87bf5aaaa585 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/lib/AST/StmtOpenMP.cpp
@@ -524,14 +524,15 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
OMPTaskgroupDirective *OMPTaskgroupDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef) {
unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
sizeof(OMPClause *) * Clauses.size(),
alignof(Stmt *));
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(Expr *));
OMPTaskgroupDirective *Dir =
new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc, Clauses.size());
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setReductionRef(ReductionRef);
Dir->setClauses(Clauses);
return Dir;
}
@@ -542,7 +543,7 @@ OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C,
unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
sizeof(OMPClause *) * NumClauses,
alignof(Stmt *));
- void *Mem = C.Allocate(Size + sizeof(Stmt *));
+ void *Mem = C.Allocate(Size + sizeof(Stmt *) + sizeof(Expr *));
return new (Mem) OMPTaskgroupDirective(NumClauses);
}
@@ -794,13 +795,14 @@ OMPTargetDataDirective *OMPTargetDataDirective::CreateEmpty(const ASTContext &C,
OMPTargetEnterDataDirective *OMPTargetEnterDataDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses) {
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
void *Mem = C.Allocate(
llvm::alignTo(sizeof(OMPTargetEnterDataDirective), alignof(OMPClause *)) +
- sizeof(OMPClause *) * Clauses.size());
+ sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
OMPTargetEnterDataDirective *Dir =
new (Mem) OMPTargetEnterDataDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
return Dir;
}
@@ -809,20 +811,20 @@ OMPTargetEnterDataDirective::CreateEmpty(const ASTContext &C, unsigned N,
EmptyShell) {
void *Mem = C.Allocate(
llvm::alignTo(sizeof(OMPTargetEnterDataDirective), alignof(OMPClause *)) +
- sizeof(OMPClause *) * N);
+ sizeof(OMPClause *) * N + sizeof(Stmt *));
return new (Mem) OMPTargetEnterDataDirective(N);
}
-OMPTargetExitDataDirective *
-OMPTargetExitDataDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses) {
+OMPTargetExitDataDirective *OMPTargetExitDataDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
void *Mem = C.Allocate(
llvm::alignTo(sizeof(OMPTargetExitDataDirective), alignof(OMPClause *)) +
- sizeof(OMPClause *) * Clauses.size());
+ sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
OMPTargetExitDataDirective *Dir =
new (Mem) OMPTargetExitDataDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
return Dir;
}
@@ -831,7 +833,7 @@ OMPTargetExitDataDirective::CreateEmpty(const ASTContext &C, unsigned N,
EmptyShell) {
void *Mem = C.Allocate(
llvm::alignTo(sizeof(OMPTargetExitDataDirective), alignof(OMPClause *)) +
- sizeof(OMPClause *) * N);
+ sizeof(OMPClause *) * N + sizeof(Stmt *));
return new (Mem) OMPTargetExitDataDirective(N);
}
@@ -1006,16 +1008,17 @@ OMPDistributeDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
return new (Mem) OMPDistributeDirective(CollapsedNum, NumClauses);
}
-OMPTargetUpdateDirective *
-OMPTargetUpdateDirective::Create(const ASTContext &C, SourceLocation StartLoc,
- SourceLocation EndLoc,
- ArrayRef<OMPClause *> Clauses) {
+OMPTargetUpdateDirective *OMPTargetUpdateDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
unsigned Size =
llvm::alignTo(sizeof(OMPTargetUpdateDirective), alignof(OMPClause *));
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * Clauses.size());
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * Clauses.size() + sizeof(Stmt *));
OMPTargetUpdateDirective *Dir =
new (Mem) OMPTargetUpdateDirective(StartLoc, EndLoc, Clauses.size());
Dir->setClauses(Clauses);
+ Dir->setAssociatedStmt(AssociatedStmt);
return Dir;
}
@@ -1024,14 +1027,15 @@ OMPTargetUpdateDirective::CreateEmpty(const ASTContext &C, unsigned NumClauses,
EmptyShell) {
unsigned Size =
llvm::alignTo(sizeof(OMPTargetUpdateDirective), alignof(OMPClause *));
- void *Mem = C.Allocate(Size + sizeof(OMPClause *) * NumClauses);
+ void *Mem =
+ C.Allocate(Size + sizeof(OMPClause *) * NumClauses + sizeof(Stmt *));
return new (Mem) OMPTargetUpdateDirective(NumClauses);
}
OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
+ const HelperExprs &Exprs, bool HasCancel) {
unsigned Size = llvm::alignTo(sizeof(OMPDistributeParallelForDirective),
alignof(OMPClause *));
void *Mem = C.Allocate(
@@ -1075,6 +1079,7 @@ OMPDistributeParallelForDirective *OMPDistributeParallelForDirective::Create(
Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
+ Dir->HasCancel = HasCancel;
return Dir;
}
@@ -1475,7 +1480,7 @@ OMPTeamsDistributeParallelForDirective *
OMPTeamsDistributeParallelForDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
+ const HelperExprs &Exprs, bool HasCancel) {
auto Size = llvm::alignTo(sizeof(OMPTeamsDistributeParallelForDirective),
alignof(OMPClause *));
void *Mem = C.Allocate(
@@ -1519,6 +1524,7 @@ OMPTeamsDistributeParallelForDirective::Create(
Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
+ Dir->HasCancel = HasCancel;
return Dir;
}
@@ -1618,7 +1624,7 @@ OMPTargetTeamsDistributeParallelForDirective *
OMPTargetTeamsDistributeParallelForDirective::Create(
const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
- const HelperExprs &Exprs) {
+ const HelperExprs &Exprs, bool HasCancel) {
auto Size =
llvm::alignTo(sizeof(OMPTargetTeamsDistributeParallelForDirective),
alignof(OMPClause *));
@@ -1664,6 +1670,7 @@ OMPTargetTeamsDistributeParallelForDirective::Create(
Dir->setCombinedCond(Exprs.DistCombinedFields.Cond);
Dir->setCombinedNextLowerBound(Exprs.DistCombinedFields.NLB);
Dir->setCombinedNextUpperBound(Exprs.DistCombinedFields.NUB);
+ Dir->HasCancel = HasCancel;
return Dir;
}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 5ebaa32b49c8..d7e668a83280 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
using namespace clang;
@@ -38,12 +39,14 @@ namespace {
unsigned IndentLevel;
clang::PrinterHelper* Helper;
PrintingPolicy Policy;
+ const ASTContext *Context;
public:
- StmtPrinter(raw_ostream &os, PrinterHelper* helper,
- const PrintingPolicy &Policy,
- unsigned Indentation = 0)
- : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {}
+ StmtPrinter(raw_ostream &os, PrinterHelper *helper,
+ const PrintingPolicy &Policy, unsigned Indentation = 0,
+ const ASTContext *Context = nullptr)
+ : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
+ Context(Context) {}
void PrintStmt(Stmt *S) {
PrintStmt(S, Policy.Indentation);
@@ -72,7 +75,8 @@ namespace {
void PrintCallArgs(CallExpr *E);
void PrintRawSEHExceptHandler(SEHExceptStmt *S);
void PrintRawSEHFinallyStmt(SEHFinallyStmt *S);
- void PrintOMPExecutableDirective(OMPExecutableDirective *S);
+ void PrintOMPExecutableDirective(OMPExecutableDirective *S,
+ bool ForceNoStmt = false);
void PrintExpr(Expr *E) {
if (E)
@@ -859,6 +863,28 @@ void OMPClausePrinter::VisitOMPTaskReductionClause(
}
}
+void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "in_reduction(";
+ NestedNameSpecifier *QualifierLoc =
+ Node->getQualifierLoc().getNestedNameSpecifier();
+ OverloadedOperatorKind OOK =
+ Node->getNameInfo().getName().getCXXOverloadedOperator();
+ if (QualifierLoc == nullptr && OOK != OO_None) {
+ // Print reduction identifier in C format
+ OS << getOperatorSpelling(OOK);
+ } else {
+ // Use C++ format
+ if (QualifierLoc != nullptr)
+ QualifierLoc->print(OS, Policy);
+ OS << Node->getNameInfo();
+ }
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
if (!Node->varlist_empty()) {
OS << "linear";
@@ -997,7 +1023,8 @@ void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
// OpenMP directives printing methods
//===----------------------------------------------------------------------===//
-void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S) {
+void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S,
+ bool ForceNoStmt) {
OMPClausePrinter Printer(OS, Policy);
ArrayRef<OMPClause *> Clauses = S->clauses();
for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
@@ -1007,7 +1034,7 @@ void StmtPrinter::PrintOMPExecutableDirective(OMPExecutableDirective *S) {
OS << ' ';
}
OS << "\n";
- if (S->hasAssociatedStmt() && S->getAssociatedStmt()) {
+ if (S->hasAssociatedStmt() && S->getAssociatedStmt() && !ForceNoStmt) {
assert(isa<CapturedStmt>(S->getAssociatedStmt()) &&
"Expected captured statement!");
Stmt *CS = cast<CapturedStmt>(S->getAssociatedStmt())->getCapturedStmt();
@@ -1136,13 +1163,13 @@ void StmtPrinter::VisitOMPTargetDataDirective(OMPTargetDataDirective *Node) {
void StmtPrinter::VisitOMPTargetEnterDataDirective(
OMPTargetEnterDataDirective *Node) {
Indent() << "#pragma omp target enter data ";
- PrintOMPExecutableDirective(Node);
+ PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
}
void StmtPrinter::VisitOMPTargetExitDataDirective(
OMPTargetExitDataDirective *Node) {
Indent() << "#pragma omp target exit data ";
- PrintOMPExecutableDirective(Node);
+ PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
}
void StmtPrinter::VisitOMPTargetParallelDirective(
@@ -1194,7 +1221,7 @@ void StmtPrinter::VisitOMPDistributeDirective(OMPDistributeDirective *Node) {
void StmtPrinter::VisitOMPTargetUpdateDirective(
OMPTargetUpdateDirective *Node) {
Indent() << "#pragma omp target update ";
- PrintOMPExecutableDirective(Node);
+ PrintOMPExecutableDirective(Node, /*ForceNoStmt=*/true);
}
void StmtPrinter::VisitOMPDistributeParallelForDirective(
@@ -1294,8 +1321,7 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
OS << "template ";
OS << Node->getNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
void StmtPrinter::VisitDependentScopeDeclRefExpr(
@@ -1306,8 +1332,7 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr(
OS << "template ";
OS << Node->getNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
@@ -1317,14 +1342,28 @@ void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
OS << "template ";
OS << Node->getNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
+}
+
+static bool isImplicitSelf(const Expr *E) {
+ if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+ if (const ImplicitParamDecl *PD =
+ dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
+ if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
+ DRE->getLocStart().isInvalid())
+ return true;
+ }
+ }
+ return false;
}
void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
if (Node->getBase()) {
- PrintExpr(Node->getBase());
- OS << (Node->isArrow() ? "->" : ".");
+ if (!Policy.SuppressImplicitBase ||
+ !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
+ PrintExpr(Node->getBase());
+ OS << (Node->isArrow() ? "->" : ".");
+ }
}
OS << *Node->getDecl();
}
@@ -1419,7 +1458,26 @@ void StmtPrinter::VisitCharacterLiteral(CharacterLiteral *Node) {
}
}
+/// Prints the given expression using the original source text. Returns true on
+/// success, false otherwise.
+static bool printExprAsWritten(raw_ostream &OS, Expr *E,
+ const ASTContext *Context) {
+ if (!Context)
+ return false;
+ bool Invalid = false;
+ StringRef Source = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(E->getSourceRange()),
+ Context->getSourceManager(), Context->getLangOpts(), &Invalid);
+ if (!Invalid) {
+ OS << Source;
+ return true;
+ }
+ return false;
+}
+
void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
+ if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+ return;
bool isSigned = Node->getType()->isSignedIntegerType();
OS << Node->getValue().toString(10, isSigned);
@@ -1456,6 +1514,7 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
default: llvm_unreachable("Unexpected type for float literal!");
case BuiltinType::Half: break; // FIXME: suffix?
case BuiltinType::Double: break; // no suffix.
+ case BuiltinType::Float16: OS << "F16"; break;
case BuiltinType::Float: OS << 'F'; break;
case BuiltinType::LongDouble: OS << 'L'; break;
case BuiltinType::Float128: OS << 'Q'; break;
@@ -1463,6 +1522,8 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
}
void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
+ if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+ return;
PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
}
@@ -1623,16 +1684,25 @@ void StmtPrinter::VisitCallExpr(CallExpr *Call) {
PrintCallArgs(Call);
OS << ")";
}
+
+static bool isImplicitThis(const Expr *E) {
+ if (const auto *TE = dyn_cast<CXXThisExpr>(E))
+ return TE->isImplicit();
+ return false;
+}
+
void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
- // FIXME: Suppress printing implicit bases (like "this")
- PrintExpr(Node->getBase());
+ if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
+ PrintExpr(Node->getBase());
- MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
- FieldDecl *ParentDecl = ParentMember
- ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : nullptr;
+ MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
+ FieldDecl *ParentDecl =
+ ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
+ : nullptr;
- if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
- OS << (Node->isArrow() ? "->" : ".");
+ if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
+ OS << (Node->isArrow() ? "->" : ".");
+ }
if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
if (FD->isAnonymousStructOrUnion())
@@ -1644,8 +1714,7 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
OS << "template ";
OS << Node->getMemberNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
void StmtPrinter::VisitObjCIsaExpr(ObjCIsaExpr *Node) {
PrintExpr(Node->getBase());
@@ -1869,7 +1938,8 @@ void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
// AtomicExpr stores its subexpressions in a permuted order.
PrintExpr(Node->getPtr());
if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
- Node->getOp() != AtomicExpr::AO__atomic_load_n) {
+ Node->getOp() != AtomicExpr::AO__atomic_load_n &&
+ Node->getOp() != AtomicExpr::AO__opencl_atomic_load) {
OS << ", ";
PrintExpr(Node->getVal1());
}
@@ -1883,7 +1953,8 @@ void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
OS << ", ";
PrintExpr(Node->getWeak());
}
- if (Node->getOp() != AtomicExpr::AO__c11_atomic_init) {
+ if (Node->getOp() != AtomicExpr::AO__c11_atomic_init &&
+ Node->getOp() != AtomicExpr::AO__opencl_atomic_init) {
OS << ", ";
PrintExpr(Node->getOrder());
}
@@ -2036,8 +2107,7 @@ void StmtPrinter::VisitUserDefinedLiteral(UserDefinedLiteral *Node) {
if (Args->size() != 1) {
OS << "operator\"\"" << Node->getUDSuffix()->getName();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Args->asArray(), Policy);
+ printTemplateArgumentList(OS, Args->asArray(), Policy);
OS << "()";
return;
}
@@ -2159,6 +2229,9 @@ void StmtPrinter::VisitLambdaExpr(LambdaExpr *Node) {
CEnd = Node->explicit_capture_end();
C != CEnd;
++C) {
+ if (C->capturesVLAType())
+ continue;
+
if (NeedComma)
OS << ", ";
NeedComma = true;
@@ -2361,8 +2434,7 @@ void StmtPrinter::VisitCXXDependentScopeMemberExpr(
OS << "template ";
OS << Node->getMemberNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
@@ -2376,8 +2448,7 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
OS << "template ";
OS << Node->getMemberNameInfo();
if (Node->hasExplicitTemplateArgs())
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, Node->template_arguments(), Policy);
+ printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
static const char *getTypeTraitName(TypeTrait TT) {
@@ -2672,11 +2743,10 @@ void Stmt::dumpPretty(const ASTContext &Context) const {
printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
}
-void Stmt::printPretty(raw_ostream &OS,
- PrinterHelper *Helper,
- const PrintingPolicy &Policy,
- unsigned Indentation) const {
- StmtPrinter P(OS, Helper, Policy, Indentation);
+void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
+ const PrintingPolicy &Policy, unsigned Indentation,
+ const ASTContext *Context) const {
+ StmtPrinter P(OS, Helper, Policy, Indentation, Context);
P.Visit(const_cast<Stmt*>(this));
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index 7ec0d1d5e017..00ef0da18bbb 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -573,6 +573,34 @@ void OMPClauseProfiler::VisitOMPTaskReductionClause(
Profiler->VisitStmt(E);
}
}
+void OMPClauseProfiler::VisitOMPInReductionClause(
+ const OMPInReductionClause *C) {
+ Profiler->VisitNestedNameSpecifier(
+ C->getQualifierLoc().getNestedNameSpecifier());
+ Profiler->VisitName(C->getNameInfo().getName());
+ VisitOMPClauseList(C);
+ VistOMPClauseWithPostUpdate(C);
+ for (auto *E : C->privates()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->lhs_exprs()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->rhs_exprs()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->reduction_ops()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->taskgroup_descriptors()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+}
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
VistOMPClauseWithPostUpdate(C);
@@ -774,6 +802,8 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
VisitOMPExecutableDirective(S);
+ if (const Expr *E = S->getReductionRef())
+ VisitStmt(E);
}
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
@@ -1354,6 +1384,10 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
case OO_GreaterEqual:
BinaryOp = BO_GE;
return Stmt::BinaryOperatorClass;
+
+ case OO_Spaceship:
+ // FIXME: Update this once we support <=> expressions.
+ llvm_unreachable("<=> expressions not supported yet");
case OO_AmpAmp:
BinaryOp = BO_LAnd;
@@ -1388,7 +1422,7 @@ static Stmt::StmtClass DecodeOperatorCall(const CXXOperatorCallExpr *S,
llvm_unreachable("Invalid overloaded operator expression");
}
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER == 1911
// Work around https://developercommunity.visualstudio.com/content/problem/84002/clang-cl-when-built-with-vc-2017-crashes-cause-vc.html
// MSVC 2017 update 3 miscompiles this function, and a clang built with it
@@ -1429,7 +1463,7 @@ void StmtProfiler::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *S) {
ID.AddInteger(S->getOperator());
}
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER == 1911
#pragma optimize("", on)
#endif
@@ -1560,6 +1594,9 @@ StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
CEnd = S->explicit_capture_end();
C != CEnd; ++C) {
+ if (C->capturesVLAType())
+ continue;
+
ID.AddInteger(C->getCaptureKind());
switch (C->getCaptureKind()) {
case LCK_StarThis:
@@ -1671,6 +1708,7 @@ void StmtProfiler::VisitCXXUnresolvedConstructExpr(
const CXXUnresolvedConstructExpr *S) {
VisitExpr(S);
VisitType(S->getTypeAsWritten());
+ ID.AddInteger(S->isListInitialization());
}
void StmtProfiler::VisitCXXDependentScopeMemberExpr(
diff --git a/lib/AST/TemplateBase.cpp b/lib/AST/TemplateBase.cpp
index e4998c37a4ef..e81c11a77825 100644
--- a/lib/AST/TemplateBase.cpp
+++ b/lib/AST/TemplateBase.cpp
@@ -1,4 +1,4 @@
-//===--- TemplateBase.cpp - Common template AST class implementation ------===//
+//===- TemplateBase.cpp - Common template AST class implementation --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,17 +14,32 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstring>
using namespace clang;
@@ -37,7 +52,7 @@ using namespace clang;
/// \param Policy the printing policy for EnumConstantDecl printing.
static void printIntegral(const TemplateArgument &TemplArg,
raw_ostream &Out, const PrintingPolicy& Policy) {
- const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
+ const Type *T = TemplArg.getIntegralType().getTypePtr();
const llvm::APSInt &Val = TemplArg.getAsIntegral();
if (const EnumType *ET = T->getAs<EnumType>()) {
@@ -415,10 +430,9 @@ void TemplateArgument::print(const PrintingPolicy &Policy,
Out << "...";
break;
- case Integral: {
+ case Integral:
printIntegral(*this, Out, Policy);
break;
- }
case Expression:
getAsExpr()->printPretty(Out, nullptr, Policy);
diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp
index 47a7d47e7a48..bd04fd8366b3 100644
--- a/lib/AST/TemplateName.cpp
+++ b/lib/AST/TemplateName.cpp
@@ -1,4 +1,4 @@
-//===--- TemplateName.cpp - C++ Template Name Representation---------------===//
+//===- TemplateName.cpp - C++ Template Name Representation ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,24 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/TemplateName.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <string>
+
using namespace clang;
-using namespace llvm;
TemplateArgument
SubstTemplateTemplateParmPackStorage::getArgumentPack() const {
@@ -131,6 +140,23 @@ DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
return Storage.dyn_cast<DependentTemplateName *>();
}
+TemplateName TemplateName::getNameToSubstitute() const {
+ TemplateDecl *Decl = getAsTemplateDecl();
+
+ // Substituting a dependent template name: preserve it as written.
+ if (!Decl)
+ return *this;
+
+ // If we have a template declaration, use the most recent non-friend
+ // declaration of that template.
+ Decl = cast<TemplateDecl>(Decl->getMostRecentDecl());
+ while (Decl->getFriendObjectKind()) {
+ Decl = cast<TemplateDecl>(Decl->getPreviousDecl());
+ assert(Decl && "all declarations of template are friends");
+ }
+ return TemplateName(Decl);
+}
+
bool TemplateName::isDependent() const {
if (TemplateDecl *Template = getAsTemplateDecl()) {
if (isa<TemplateTemplateParmDecl>(Template))
@@ -209,7 +235,7 @@ TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
TemplateName N) {
std::string NameStr;
- raw_string_ostream OS(NameStr);
+ llvm::raw_string_ostream OS(NameStr);
LangOptions LO;
LO.CPlusPlus = true;
LO.Bool = true;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index d21781dc3899..38f2a16fa16f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1,4 +1,4 @@
-//===--- Type.cpp - Type representation and manipulation ------------------===//
+//===- Type.cpp - Type representation and manipulation --------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,20 +12,44 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/Type.h"
+#include "Linkage.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/TypeVisitor.h"
+#include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetCXXABI.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Basic/Visibility.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
using namespace clang;
bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const {
@@ -125,12 +149,10 @@ DependentSizedArrayType::DependentSizedArrayType(const ASTContext &Context,
Expr *e, ArraySizeModifier sm,
unsigned tq,
SourceRange brackets)
- : ArrayType(DependentSizedArray, et, can, sm, tq,
+ : ArrayType(DependentSizedArray, et, can, sm, tq,
(et->containsUnexpandedParameterPack() ||
(e && e->containsUnexpandedParameterPack()))),
- Context(Context), SizeExpr((Stmt*) e), Brackets(brackets)
-{
-}
+ Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {}
void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context,
@@ -152,13 +174,11 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(const
SourceLocation loc)
: Type(DependentSizedExtVector, can, /*Dependent=*/true,
/*InstantiationDependent=*/true,
- ElementType->isVariablyModifiedType(),
+ ElementType->isVariablyModifiedType(),
(ElementType->containsUnexpandedParameterPack() ||
(SizeExpr && SizeExpr->containsUnexpandedParameterPack()))),
Context(Context), SizeExpr(SizeExpr), ElementType(ElementType),
- loc(loc)
-{
-}
+ loc(loc) {}
void
DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
@@ -168,18 +188,37 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID,
SizeExpr->Profile(ID, Context, true);
}
+DependentAddressSpaceType::DependentAddressSpaceType(
+ const ASTContext &Context, QualType PointeeType, QualType can,
+ Expr *AddrSpaceExpr, SourceLocation loc)
+ : Type(DependentAddressSpace, can, /*Dependent=*/true,
+ /*InstantiationDependent=*/true,
+ PointeeType->isVariablyModifiedType(),
+ (PointeeType->containsUnexpandedParameterPack() ||
+ (AddrSpaceExpr &&
+ AddrSpaceExpr->containsUnexpandedParameterPack()))),
+ Context(Context), AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType),
+ loc(loc) {}
+
+void DependentAddressSpaceType::Profile(llvm::FoldingSetNodeID &ID,
+ const ASTContext &Context,
+ QualType PointeeType,
+ Expr *AddrSpaceExpr) {
+ ID.AddPointer(PointeeType.getAsOpaquePtr());
+ AddrSpaceExpr->Profile(ID, Context, true);
+}
+
VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType,
VectorKind vecKind)
: VectorType(Vector, vecType, nElements, canonType, vecKind) {}
VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType, VectorKind vecKind)
- : Type(tc, canonType, vecType->isDependentType(),
- vecType->isInstantiationDependentType(),
- vecType->isVariablyModifiedType(),
- vecType->containsUnexpandedParameterPack()),
- ElementType(vecType)
-{
+ : Type(tc, canonType, vecType->isDependentType(),
+ vecType->isInstantiationDependentType(),
+ vecType->isVariablyModifiedType(),
+ vecType->containsUnexpandedParameterPack()),
+ ElementType(vecType) {
VectorTypeBits.VecKind = vecKind;
VectorTypeBits.NumElements = nElements;
}
@@ -354,11 +393,13 @@ const Type *Type::getUnqualifiedDesugaredType() const {
}
}
}
+
bool Type::isClassType() const {
if (const RecordType *RT = getAs<RecordType>())
return RT->getDecl()->isClass();
return false;
}
+
bool Type::isStructureType() const {
if (const RecordType *RT = getAs<RecordType>())
return RT->getDecl()->isStruct();
@@ -381,6 +422,7 @@ bool Type::isStructureOrClassType() const {
}
return false;
}
+
bool Type::isVoidPointerType() const {
if (const PointerType *PT = getAs<PointerType>())
return PT->getPointeeType()->isVoidType();
@@ -534,12 +576,11 @@ bool Type::isObjCInertUnsafeUnretainedType() const {
ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,
QualType can,
ArrayRef<ObjCProtocolDecl *> protocols)
- : Type(ObjCTypeParam, can, can->isDependentType(),
- can->isInstantiationDependentType(),
- can->isVariablyModifiedType(),
- /*ContainsUnexpandedParameterPack=*/false),
- OTPDecl(const_cast<ObjCTypeParamDecl*>(D))
-{
+ : Type(ObjCTypeParam, can, can->isDependentType(),
+ can->isInstantiationDependentType(),
+ can->isVariablyModifiedType(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ OTPDecl(const_cast<ObjCTypeParamDecl*>(D)) {
initialize(protocols);
}
@@ -547,12 +588,11 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
bool isKindOf)
- : Type(ObjCObject, Canonical, Base->isDependentType(),
- Base->isInstantiationDependentType(),
- Base->isVariablyModifiedType(),
- Base->containsUnexpandedParameterPack()),
- BaseType(Base)
-{
+ : Type(ObjCObject, Canonical, Base->isDependentType(),
+ Base->isInstantiationDependentType(),
+ Base->isVariablyModifiedType(),
+ Base->containsUnexpandedParameterPack()),
+ BaseType(Base) {
ObjCObjectTypeBits.IsKindOf = isKindOf;
ObjCObjectTypeBits.NumTypeArgs = typeArgs.size();
@@ -603,13 +643,13 @@ ArrayRef<QualType> ObjCObjectType::getTypeArgs() const {
if (auto objcObject = getBaseType()->getAs<ObjCObjectType>()) {
// Terminate when we reach an interface type.
if (isa<ObjCInterfaceType>(objcObject))
- return { };
+ return {};
return objcObject->getTypeArgs();
}
// No type arguments.
- return { };
+ return {};
}
bool ObjCObjectType::isKindOfType() const {
@@ -645,7 +685,7 @@ QualType ObjCObjectType::stripObjCKindOfTypeAndQuals(
return ctx.getObjCObjectType(ctx.getQualifiedType(baseType,
splitBaseType.Quals),
getTypeArgsAsWritten(),
- /*protocols=*/{ },
+ /*protocols=*/{},
/*isKindOf=*/false);
}
@@ -658,10 +698,10 @@ const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals(
return ctx.getObjCObjectPointerType(obj)->castAs<ObjCObjectPointerType>();
}
-namespace {
-
template<typename F>
-QualType simpleTransform(ASTContext &ctx, QualType type, F &&f);
+static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f);
+
+namespace {
/// Visitor used by simpleTransform() to perform the transformation.
template<typename F>
@@ -675,7 +715,8 @@ struct SimpleTransformVisitor
}
public:
- SimpleTransformVisitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { }
+ SimpleTransformVisitor(ASTContext &ctx, F &&f)
+ : Ctx(ctx), TheFunc(std::move(f)) {}
// None of the clients of this transformation can occur where
// there are dependent types, so skip dependent types.
@@ -1044,10 +1085,12 @@ public:
#undef TRIVIAL_TYPE_CLASS
};
+} // namespace
+
/// Perform a simple type transformation that does not change the
/// semantics of the type.
template<typename F>
-QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
+static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
// Transform the type. If it changed, return the transformed result.
QualType transformed = f(type);
if (transformed.getAsOpaquePtr() != type.getAsOpaquePtr())
@@ -1067,8 +1110,6 @@ QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) {
return ctx.getQualifiedType(result, splitType.Quals);
}
-} // end anonymous namespace
-
/// Substitute the given type arguments for Objective-C type
/// parameters within the given type, recursively.
QualType QualType::substObjCTypeArgs(
@@ -1233,7 +1274,7 @@ QualType QualType::substObjCTypeArgs(
if (typeArgs.empty() &&
context != ObjCSubstitutionContext::Superclass) {
return ctx.getObjCObjectType(
- objcObjectType->getBaseType(), { },
+ objcObjectType->getBaseType(), {},
protocols,
objcObjectType->isKindOfTypeAsWritten());
}
@@ -1343,7 +1384,7 @@ Optional<ArrayRef<QualType>> Type::getObjCSubstitutions(
objectType = objectPointerType->getObjectType();
} else if (getAs<BlockPointerType>()) {
ASTContext &ctx = dc->getParentASTContext();
- objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, { }, { })
+ objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, {}, {})
->castAs<ObjCObjectType>();
} else {
objectType = getAs<ObjCObjectType>();
@@ -1522,6 +1563,7 @@ const ObjCObjectType *Type::getAsObjCInterfaceType() const {
}
return nullptr;
}
+
const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const {
if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>()) {
if (OPT->getInterfaceType())
@@ -1559,14 +1601,17 @@ TagDecl *Type::getAsTagDecl() const {
}
namespace {
+
class GetContainedDeducedTypeVisitor :
public TypeVisitor<GetContainedDeducedTypeVisitor, Type*> {
bool Syntactic;
+
public:
GetContainedDeducedTypeVisitor(bool Syntactic = false)
: Syntactic(Syntactic) {}
using TypeVisitor<GetContainedDeducedTypeVisitor, Type*>::Visit;
+
Type *Visit(QualType T) {
if (T.isNull())
return nullptr;
@@ -1579,50 +1624,64 @@ namespace {
}
// Only these types can contain the desired 'auto' type.
+
Type *VisitElaboratedType(const ElaboratedType *T) {
return Visit(T->getNamedType());
}
+
Type *VisitPointerType(const PointerType *T) {
return Visit(T->getPointeeType());
}
+
Type *VisitBlockPointerType(const BlockPointerType *T) {
return Visit(T->getPointeeType());
}
+
Type *VisitReferenceType(const ReferenceType *T) {
return Visit(T->getPointeeTypeAsWritten());
}
+
Type *VisitMemberPointerType(const MemberPointerType *T) {
return Visit(T->getPointeeType());
}
+
Type *VisitArrayType(const ArrayType *T) {
return Visit(T->getElementType());
}
+
Type *VisitDependentSizedExtVectorType(
const DependentSizedExtVectorType *T) {
return Visit(T->getElementType());
}
+
Type *VisitVectorType(const VectorType *T) {
return Visit(T->getElementType());
}
+
Type *VisitFunctionProtoType(const FunctionProtoType *T) {
if (Syntactic && T->hasTrailingReturn())
return const_cast<FunctionProtoType*>(T);
return VisitFunctionType(T);
}
+
Type *VisitFunctionType(const FunctionType *T) {
return Visit(T->getReturnType());
}
+
Type *VisitParenType(const ParenType *T) {
return Visit(T->getInnerType());
}
+
Type *VisitAttributedType(const AttributedType *T) {
return Visit(T->getModifiedType());
}
+
Type *VisitAdjustedType(const AdjustedType *T) {
return Visit(T->getOriginalType());
}
};
-}
+
+} // namespace
DeducedType *Type::getContainedDeducedType() const {
return cast_or_null<DeducedType>(
@@ -1673,7 +1732,6 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
return false;
}
-
bool Type::isIntegralOrUnscopedEnumerationType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
@@ -1689,8 +1747,6 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
return false;
}
-
-
bool Type::isCharType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() == BuiltinType::Char_U ||
@@ -2015,7 +2071,7 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
// We return false for that case. Except for incomplete arrays of PODs, which
// are PODs according to the standard.
if (isNull())
- return 0;
+ return false;
if ((*this)->isIncompleteArrayType())
return Context.getBaseElementType(*this).isCXX98PODType(Context);
@@ -2063,7 +2119,7 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
// We return false for that case. Except for incomplete arrays of PODs, which
// are PODs according to the standard.
if (isNull())
- return 0;
+ return false;
if ((*this)->isArrayType())
return Context.getBaseElementType(*this).isTrivialType(Context);
@@ -2563,6 +2619,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "double";
case LongDouble:
return "long double";
+ case Float16:
+ return "_Float16";
case Float128:
return "__float128";
case WChar_S:
@@ -2835,7 +2893,6 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result,
const QualType *ArgTys, unsigned NumParams,
const ExtProtoInfo &epi,
const ASTContext &Context, bool Canonical) {
-
// We have to be careful not to get ambiguous profile encodings.
// Note that valid type pointers are never ambiguous with anything else.
//
@@ -2897,12 +2954,11 @@ QualType TypedefType::desugar() const {
}
TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
- : Type(TypeOfExpr, can, E->isTypeDependent(),
- E->isInstantiationDependent(),
- E->getType()->isVariablyModifiedType(),
- E->containsUnexpandedParameterPack()),
- TOExpr(E) {
-}
+ : Type(TypeOfExpr, can, E->isTypeDependent(),
+ E->isInstantiationDependent(),
+ E->getType()->isVariablyModifiedType(),
+ E->containsUnexpandedParameterPack()),
+ TOExpr(E) {}
bool TypeOfExprType::isSugared() const {
return !TOExpr->isTypeDependent();
@@ -2924,13 +2980,11 @@ DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can)
// C++11 [temp.type]p2: "If an expression e involves a template parameter,
// decltype(e) denotes a unique dependent type." Hence a decltype type is
// type-dependent even if its expression is only instantiation-dependent.
- : Type(Decltype, can, E->isInstantiationDependent(),
- E->isInstantiationDependent(),
- E->getType()->isVariablyModifiedType(),
- E->containsUnexpandedParameterPack()),
- E(E),
- UnderlyingType(underlyingType) {
-}
+ : Type(Decltype, can, E->isInstantiationDependent(),
+ E->isInstantiationDependent(),
+ E->getType()->isVariablyModifiedType(),
+ E->containsUnexpandedParameterPack()),
+ E(E), UnderlyingType(underlyingType) {}
bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); }
@@ -2942,7 +2996,7 @@ QualType DecltypeType::desugar() const {
}
DependentDecltypeType::DependentDecltypeType(const ASTContext &Context, Expr *E)
- : DecltypeType(E, Context.DependentTy), Context(Context) { }
+ : DecltypeType(E, Context.DependentTy), Context(Context) {}
void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID,
const ASTContext &Context, Expr *E) {
@@ -2953,26 +3007,23 @@ UnaryTransformType::UnaryTransformType(QualType BaseType,
QualType UnderlyingType,
UTTKind UKind,
QualType CanonicalType)
- : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(),
- BaseType->isInstantiationDependentType(),
- BaseType->isVariablyModifiedType(),
- BaseType->containsUnexpandedParameterPack())
- , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind)
-{}
+ : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(),
+ BaseType->isInstantiationDependentType(),
+ BaseType->isVariablyModifiedType(),
+ BaseType->containsUnexpandedParameterPack()),
+ BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {}
DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C,
QualType BaseType,
UTTKind UKind)
- : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType())
-{}
-
+ : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {}
TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
- : Type(TC, can, D->isDependentType(),
- /*InstantiationDependent=*/D->isDependentType(),
- /*VariablyModified=*/false,
- /*ContainsUnexpandedParameterPack=*/false),
- decl(const_cast<TagDecl*>(D)) {}
+ : Type(TC, can, D->isDependentType(),
+ /*InstantiationDependent=*/D->isDependentType(),
+ /*VariablyModified=*/false,
+ /*ContainsUnexpandedParameterPack=*/false),
+ decl(const_cast<TagDecl*>(D)) {}
static TagDecl *getInterestingTagDecl(TagDecl *decl) {
for (auto I : decl->redecls()) {
@@ -2991,6 +3042,19 @@ bool TagType::isBeingDefined() const {
return getDecl()->isBeingDefined();
}
+bool RecordType::hasConstFields() const {
+ for (FieldDecl *FD : getDecl()->fields()) {
+ QualType FieldTy = FD->getType();
+ if (FieldTy.isConstQualified())
+ return true;
+ FieldTy = FieldTy.getCanonicalType();
+ if (const RecordType *FieldRecTy = FieldTy->getAs<RecordType>())
+ if (FieldRecTy->hasConstFields())
+ return true;
+ }
+ return false;
+}
+
bool AttributedType::isQualifier() const {
switch (getAttrKind()) {
// These are type qualifiers in the traditional C sense: they annotate
@@ -3104,11 +3168,9 @@ SubstTemplateTypeParmPackType::
SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
QualType Canon,
const TemplateArgument &ArgPack)
- : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
- Replaced(Param),
- Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size())
-{
-}
+ : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
+ Replaced(Param),
+ Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {}
TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
@@ -3275,11 +3337,13 @@ public:
L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType());
}
};
-}
+
+} // namespace
static CachedProperties computeCachedProperties(const Type *T);
namespace clang {
+
/// The type-property cache. This is templated so as to be
/// instantiated at an internal type to prevent unnecessary symbol
/// leakage.
@@ -3317,13 +3381,19 @@ public:
T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType();
}
};
-}
+
+} // namespace clang
// Instantiate the friend template at a private class. In a
// reasonable implementation, these symbols will be internal.
// It is terrible that this is the best way to accomplish this.
-namespace { class Private {}; }
-typedef TypePropertyCache<Private> Cache;
+namespace {
+
+class Private {};
+
+} // namespace
+
+using Cache = TypePropertyCache<Private>;
static CachedProperties computeCachedProperties(const Type *T) {
switch (T->getTypeClass()) {
@@ -3428,9 +3498,7 @@ bool Type::hasUnnamedOrLocalType() const {
return TypeBits.hasLocalOrUnnamedType();
}
-static LinkageInfo computeLinkageInfo(QualType T);
-
-static LinkageInfo computeLinkageInfo(const Type *T) {
+LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
switch (T->getTypeClass()) {
#define TYPE(Class,Base)
#define NON_CANONICAL_TYPE(Class,Base) case Type::Class:
@@ -3454,75 +3522,78 @@ static LinkageInfo computeLinkageInfo(const Type *T) {
case Type::Record:
case Type::Enum:
- return cast<TagType>(T)->getDecl()->getLinkageAndVisibility();
+ return getDeclLinkageAndVisibility(cast<TagType>(T)->getDecl());
case Type::Complex:
- return computeLinkageInfo(cast<ComplexType>(T)->getElementType());
+ return computeTypeLinkageInfo(cast<ComplexType>(T)->getElementType());
case Type::Pointer:
- return computeLinkageInfo(cast<PointerType>(T)->getPointeeType());
+ return computeTypeLinkageInfo(cast<PointerType>(T)->getPointeeType());
case Type::BlockPointer:
- return computeLinkageInfo(cast<BlockPointerType>(T)->getPointeeType());
+ return computeTypeLinkageInfo(cast<BlockPointerType>(T)->getPointeeType());
case Type::LValueReference:
case Type::RValueReference:
- return computeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
+ return computeTypeLinkageInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
const MemberPointerType *MPT = cast<MemberPointerType>(T);
- LinkageInfo LV = computeLinkageInfo(MPT->getClass());
- LV.merge(computeLinkageInfo(MPT->getPointeeType()));
+ LinkageInfo LV = computeTypeLinkageInfo(MPT->getClass());
+ LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
return LV;
}
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
- return computeLinkageInfo(cast<ArrayType>(T)->getElementType());
+ return computeTypeLinkageInfo(cast<ArrayType>(T)->getElementType());
case Type::Vector:
case Type::ExtVector:
- return computeLinkageInfo(cast<VectorType>(T)->getElementType());
+ return computeTypeLinkageInfo(cast<VectorType>(T)->getElementType());
case Type::FunctionNoProto:
- return computeLinkageInfo(cast<FunctionType>(T)->getReturnType());
+ return computeTypeLinkageInfo(cast<FunctionType>(T)->getReturnType());
case Type::FunctionProto: {
const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
- LinkageInfo LV = computeLinkageInfo(FPT->getReturnType());
+ LinkageInfo LV = computeTypeLinkageInfo(FPT->getReturnType());
for (const auto &ai : FPT->param_types())
- LV.merge(computeLinkageInfo(ai));
+ LV.merge(computeTypeLinkageInfo(ai));
return LV;
}
case Type::ObjCInterface:
- return cast<ObjCInterfaceType>(T)->getDecl()->getLinkageAndVisibility();
+ return getDeclLinkageAndVisibility(cast<ObjCInterfaceType>(T)->getDecl());
case Type::ObjCObject:
- return computeLinkageInfo(cast<ObjCObjectType>(T)->getBaseType());
+ return computeTypeLinkageInfo(cast<ObjCObjectType>(T)->getBaseType());
case Type::ObjCObjectPointer:
- return computeLinkageInfo(cast<ObjCObjectPointerType>(T)->getPointeeType());
+ return computeTypeLinkageInfo(
+ cast<ObjCObjectPointerType>(T)->getPointeeType());
case Type::Atomic:
- return computeLinkageInfo(cast<AtomicType>(T)->getValueType());
+ return computeTypeLinkageInfo(cast<AtomicType>(T)->getValueType());
case Type::Pipe:
- return computeLinkageInfo(cast<PipeType>(T)->getElementType());
+ return computeTypeLinkageInfo(cast<PipeType>(T)->getElementType());
}
llvm_unreachable("unhandled type class");
}
-static LinkageInfo computeLinkageInfo(QualType T) {
- return computeLinkageInfo(T.getTypePtr());
-}
-
bool Type::isLinkageValid() const {
if (!TypeBits.isCacheValid())
return true;
- return computeLinkageInfo(getCanonicalTypeInternal()).getLinkage() ==
- TypeBits.getLinkage();
+ Linkage L = LinkageComputer{}
+ .computeTypeLinkageInfo(getCanonicalTypeInternal())
+ .getLinkage();
+ return L == TypeBits.getLinkage();
}
-LinkageInfo Type::getLinkageAndVisibility() const {
- if (!isCanonicalUnqualified())
- return computeLinkageInfo(getCanonicalTypeInternal());
+LinkageInfo LinkageComputer::getTypeLinkageAndVisibility(const Type *T) {
+ if (!T->isCanonicalUnqualified())
+ return computeTypeLinkageInfo(T->getCanonicalTypeInternal());
- LinkageInfo LV = computeLinkageInfo(this);
- assert(LV.getLinkage() == getLinkage());
+ LinkageInfo LV = computeTypeLinkageInfo(T);
+ assert(LV.getLinkage() == T->getLinkage());
return LV;
}
+LinkageInfo Type::getLinkageAndVisibility() const {
+ return LinkageComputer{}.getTypeLinkageAndVisibility(this);
+}
+
Optional<NullabilityKind> Type::getNullability(const ASTContext &context) const {
QualType type(this, 0);
do {
@@ -3634,6 +3705,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
+ case Type::DependentAddressSpace:
case Type::FunctionProto:
case Type::FunctionNoProto:
case Type::Record:
@@ -3748,11 +3820,13 @@ bool Type::isObjCIndependentClassType() const {
return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>();
return false;
}
+
bool Type::isObjCRetainableType() const {
return isObjCObjectPointerType() ||
isBlockPointerType() ||
isObjCNSObjectType();
}
+
bool Type::isObjCIndirectLifetimeType() const {
if (isObjCLifetimeType())
return true;
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index c9a268655723..b05c5fc68096 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -1,4 +1,4 @@
-//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===//
+//===- TypeLoc.cpp - Type Source Info Wrapper -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,8 +14,19 @@
#include "clang/AST/TypeLoc.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
#include "clang/AST/TypeLocVisitor.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Specifiers.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
using namespace clang;
static const unsigned TypeLocMaxDataAlign = alignof(void *);
@@ -25,16 +36,18 @@ static const unsigned TypeLocMaxDataAlign = alignof(void *);
//===----------------------------------------------------------------------===//
namespace {
- class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
- public:
+
+class TypeLocRanger : public TypeLocVisitor<TypeLocRanger, SourceRange> {
+public:
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getLocalSourceRange(); \
- }
+ SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getLocalSourceRange(); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+
+} // namespace
SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
if (TL.isNull()) return SourceRange();
@@ -42,16 +55,18 @@ SourceRange TypeLoc::getLocalSourceRangeImpl(TypeLoc TL) {
}
namespace {
- class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
- public:
+
+class TypeAligner : public TypeLocVisitor<TypeAligner, unsigned> {
+public:
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getLocalDataAlignment(); \
- }
+ unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getLocalDataAlignment(); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+
+} // namespace
/// \brief Returns the alignment of the type source info data block.
unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
@@ -60,16 +75,18 @@ unsigned TypeLoc::getLocalAlignmentForType(QualType Ty) {
}
namespace {
- class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
- public:
+
+class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> {
+public:
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getLocalDataSize(); \
- }
+ unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getLocalDataSize(); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+
+} // namespace
/// \brief Returns the size of the type source info data block.
unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
@@ -88,16 +105,18 @@ unsigned TypeLoc::getFullDataSizeForType(QualType Ty) {
}
namespace {
- class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
- public:
+
+class NextLoc : public TypeLocVisitor<NextLoc, TypeLoc> {
+public:
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return TyLoc.getNextTypeLoc(); \
- }
+ TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return TyLoc.getNextTypeLoc(); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+
+} // namespace
/// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
/// TypeLoc is a PointerLoc and next TypeLoc is for "int".
@@ -127,20 +146,22 @@ void TypeLoc::initializeImpl(ASTContext &Context, TypeLoc TL,
}
namespace {
- class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
- TypeLoc Source;
- public:
- TypeLocCopier(TypeLoc source) : Source(source) { }
+
+class TypeLocCopier : public TypeLocVisitor<TypeLocCopier> {
+ TypeLoc Source;
+
+public:
+ TypeLocCopier(TypeLoc source) : Source(source) {}
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) { \
- dest.copyLocal(Source.castAs<CLASS##TypeLoc>()); \
- }
+ void Visit##CLASS##TypeLoc(CLASS##TypeLoc dest) { \
+ dest.copyLocal(Source.castAs<CLASS##TypeLoc>()); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+} // namespace
void TypeLoc::copy(TypeLoc other) {
assert(getFullDataSize() == other.getFullDataSize());
@@ -243,22 +264,22 @@ SourceLocation TypeLoc::getEndLoc() const {
}
}
-
namespace {
- struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
- // Overload resolution does the real work for us.
- static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
- static bool isTypeSpec(TypeLoc _) { return false; }
+
+struct TSTChecker : public TypeLocVisitor<TSTChecker, bool> {
+ // Overload resolution does the real work for us.
+ static bool isTypeSpec(TypeSpecTypeLoc _) { return true; }
+ static bool isTypeSpec(TypeLoc _) { return false; }
#define ABSTRACT_TYPELOC(CLASS, PARENT)
#define TYPELOC(CLASS, PARENT) \
- bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
- return isTypeSpec(TyLoc); \
- }
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \
+ return isTypeSpec(TyLoc); \
+ }
#include "clang/AST/TypeLocNodes.def"
- };
-}
+};
+} // namespace
/// \brief Determines if the given type loc corresponds to a
/// TypeSpecTypeLoc. Since there is not actually a TypeSpecType in
@@ -319,6 +340,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
+ case BuiltinType::Float16:
case BuiltinType::Float128:
llvm_unreachable("Builtin type needs extra local data!");
// Fall through, if the impossible happens.
@@ -363,7 +385,7 @@ SourceLocation TypeLoc::findNullabilityLoc() const {
return attributedLoc.getAttrNameLoc();
}
- return SourceLocation();
+ return {};
}
TypeLoc TypeLoc::findExplicitQualifierLoc() const {
@@ -384,7 +406,7 @@ TypeLoc TypeLoc::findExplicitQualifierLoc() const {
return atomic;
}
- return TypeLoc();
+ return {};
}
void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
@@ -422,6 +444,15 @@ void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
getUnderlyingType(), Loc);
}
+void UnaryTransformTypeLoc::initializeLocal(ASTContext &Context,
+ SourceLocation Loc) {
+ setKWLoc(Loc);
+ setRParenLoc(Loc);
+ setLParenLoc(Loc);
+ this->setUnderlyingTInfo(
+ Context.getTrivialTypeSourceInfo(getTypePtr()->getBaseType(), Loc));
+}
+
void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
setElaboratedKeywordLoc(Loc);
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 15c63bf4ed98..35e0b75f3c22 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -222,6 +222,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::LValueReference:
case Type::RValueReference:
case Type::MemberPointer:
+ case Type::DependentAddressSpace:
case Type::DependentSizedExtVector:
case Type::Vector:
case Type::ExtVector:
@@ -527,6 +528,19 @@ void TypePrinter::printDependentSizedArrayAfter(
printAfter(T->getElementType(), OS);
}
+void TypePrinter::printDependentAddressSpaceBefore(
+ const DependentAddressSpaceType *T, raw_ostream &OS) {
+ printBefore(T->getPointeeType(), OS);
+}
+void TypePrinter::printDependentAddressSpaceAfter(
+ const DependentAddressSpaceType *T, raw_ostream &OS) {
+ OS << " __attribute__((address_space(";
+ if (T->getAddrSpaceExpr())
+ T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);
+ OS << ")))";
+ printAfter(T->getPointeeType(), OS);
+}
+
void TypePrinter::printDependentSizedExtVectorBefore(
const DependentSizedExtVectorType *T,
raw_ostream &OS) {
@@ -665,6 +679,8 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
auto EPI = T->getExtParameterInfo(i);
if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";
+ if (EPI.isNoEscape())
+ OS << "__attribute__((noescape)) ";
auto ABI = EPI.getABI();
if (ABI != ParameterABI::Ordinary)
OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) ";
@@ -966,8 +982,7 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
OS << Spec->getIdentifier()->getName();
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, TemplateArgs.asArray(), Policy);
+ printTemplateArgumentList(OS, TemplateArgs.asArray(), Policy);
OS << "::";
} else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
@@ -1054,7 +1069,7 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
Args = TemplateArgs.asArray();
}
IncludeStrongLifetimeRAII Strong(Policy);
- TemplateSpecializationType::PrintTemplateArgumentList(OS, Args, Policy);
+ printTemplateArgumentList(OS, Args, Policy);
}
spaceBeforePlaceHolder(OS);
@@ -1113,8 +1128,7 @@ void TypePrinter::printTemplateSpecializationBefore(
IncludeStrongLifetimeRAII Strong(Policy);
T->getTemplateName().print(OS, Policy);
- TemplateSpecializationType::PrintTemplateArgumentList(
- OS, T->template_arguments(), Policy);
+ printTemplateArgumentList(OS, T->template_arguments(), Policy);
spaceBeforePlaceHolder(OS);
}
void TypePrinter::printTemplateSpecializationAfter(
@@ -1182,19 +1196,18 @@ void TypePrinter::printDependentNameAfter(const DependentNameType *T,
void TypePrinter::printDependentTemplateSpecializationBefore(
const DependentTemplateSpecializationType *T, raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
-
+
OS << TypeWithKeyword::getKeywordName(T->getKeyword());
if (T->getKeyword() != ETK_None)
OS << " ";
-
+
if (T->getQualifier())
- T->getQualifier()->print(OS, Policy);
+ T->getQualifier()->print(OS, Policy);
OS << T->getIdentifier()->getName();
- TemplateSpecializationType::PrintTemplateArgumentList(OS,
- T->template_arguments(),
- Policy);
+ printTemplateArgumentList(OS, T->template_arguments(), Policy);
spaceBeforePlaceHolder(OS);
}
+
void TypePrinter::printDependentTemplateSpecializationAfter(
const DependentTemplateSpecializationType *T, raw_ostream &OS) { }
@@ -1304,7 +1317,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
default: llvm_unreachable("This attribute should have been handled already");
case AttributedType::attr_address_space:
OS << "address_space(";
- OS << T->getEquivalentType().getAddressSpace();
+ // FIXME: printing the raw LangAS value is wrong. This should probably
+ // use the same code as Qualifiers::print()
+ OS << (unsigned)T->getEquivalentType().getAddressSpace();
OS << ')';
break;
@@ -1503,41 +1518,39 @@ void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,
OS << '*';
}
}
+
void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,
raw_ostream &OS) { }
-void TemplateSpecializationType::
- PrintTemplateArgumentList(raw_ostream &OS,
- const TemplateArgumentListInfo &Args,
- const PrintingPolicy &Policy) {
- return PrintTemplateArgumentList(OS,
- Args.arguments(),
- Policy);
+static
+const TemplateArgument &getArgument(const TemplateArgument &A) { return A; }
+
+static const TemplateArgument &getArgument(const TemplateArgumentLoc &A) {
+ return A.getArgument();
}
-void TemplateSpecializationType::PrintTemplateArgumentList(
- raw_ostream &OS, ArrayRef<TemplateArgument> Args,
- const PrintingPolicy &Policy, bool SkipBrackets) {
+template<typename TA>
+static void printTo(raw_ostream &OS, ArrayRef<TA> Args,
+ const PrintingPolicy &Policy, bool SkipBrackets) {
const char *Comma = Policy.MSVCFormatting ? "," : ", ";
if (!SkipBrackets)
OS << '<';
- bool needSpace = false;
+ bool NeedSpace = false;
bool FirstArg = true;
- for (const TemplateArgument &Arg : Args) {
+ for (const auto &Arg : Args) {
// Print the argument into a string.
SmallString<128> Buf;
llvm::raw_svector_ostream ArgOS(Buf);
- if (Arg.getKind() == TemplateArgument::Pack) {
- if (Arg.pack_size() && !FirstArg)
+ const TemplateArgument &Argument = getArgument(Arg);
+ if (Argument.getKind() == TemplateArgument::Pack) {
+ if (Argument.pack_size() && !FirstArg)
OS << Comma;
- PrintTemplateArgumentList(ArgOS,
- Arg.getPackAsArray(),
- Policy, true);
+ printTo(ArgOS, Argument.getPackAsArray(), Policy, true);
} else {
if (!FirstArg)
OS << Comma;
- Arg.print(Policy, ArgOS);
+ Argument.print(Policy, ArgOS);
}
StringRef ArgString = ArgOS.str();
@@ -1549,65 +1562,36 @@ void TemplateSpecializationType::PrintTemplateArgumentList(
OS << ArgString;
- needSpace = (!ArgString.empty() && ArgString.back() == '>');
+ NeedSpace = (!ArgString.empty() && ArgString.back() == '>');
FirstArg = false;
}
// If the last character of our string is '>', add another space to
// keep the two '>''s separate tokens. We don't *have* to do this in
// C++0x, but it's still good hygiene.
- if (needSpace)
+ if (NeedSpace)
OS << ' ';
if (!SkipBrackets)
OS << '>';
}
-// Sadly, repeat all that with TemplateArgLoc.
-void TemplateSpecializationType::
-PrintTemplateArgumentList(raw_ostream &OS,
- ArrayRef<TemplateArgumentLoc> Args,
- const PrintingPolicy &Policy) {
- OS << '<';
- const char *Comma = Policy.MSVCFormatting ? "," : ", ";
-
- bool needSpace = false;
- bool FirstArg = true;
- for (const TemplateArgumentLoc &Arg : Args) {
- if (!FirstArg)
- OS << Comma;
-
- // Print the argument into a string.
- SmallString<128> Buf;
- llvm::raw_svector_ostream ArgOS(Buf);
- if (Arg.getArgument().getKind() == TemplateArgument::Pack) {
- PrintTemplateArgumentList(ArgOS,
- Arg.getArgument().getPackAsArray(),
- Policy, true);
- } else {
- Arg.getArgument().print(Policy, ArgOS);
- }
- StringRef ArgString = ArgOS.str();
-
- // If this is the first argument and its string representation
- // begins with the global scope specifier ('::foo'), add a space
- // to avoid printing the diagraph '<:'.
- if (FirstArg && !ArgString.empty() && ArgString[0] == ':')
- OS << ' ';
-
- OS << ArgString;
-
- needSpace = (!ArgString.empty() && ArgString.back() == '>');
- FirstArg = false;
- }
+void clang::printTemplateArgumentList(raw_ostream &OS,
+ const TemplateArgumentListInfo &Args,
+ const PrintingPolicy &Policy) {
+ return printTo(OS, Args.arguments(), Policy, false);
+}
- // If the last character of our string is '>', add another space to
- // keep the two '>''s separate tokens. We don't *have* to do this in
- // C++0x, but it's still good hygiene.
- if (needSpace)
- OS << ' ';
+void clang::printTemplateArgumentList(raw_ostream &OS,
+ ArrayRef<TemplateArgument> Args,
+ const PrintingPolicy &Policy) {
+ printTo(OS, Args, Policy, false);
+}
- OS << '>';
+void clang::printTemplateArgumentList(raw_ostream &OS,
+ ArrayRef<TemplateArgumentLoc> Args,
+ const PrintingPolicy &Policy) {
+ printTo(OS, Args, Policy, false);
}
std::string Qualifiers::getAsString() const {
@@ -1629,7 +1613,7 @@ bool Qualifiers::isEmptyWhenPrinted(const PrintingPolicy &Policy) const {
if (getCVRQualifiers())
return false;
- if (getAddressSpace())
+ if (getAddressSpace() != LangAS::Default)
return false;
if (getObjCGCAttr())
@@ -1660,17 +1644,21 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
OS << "__unaligned";
addSpace = true;
}
- if (unsigned addrspace = getAddressSpace()) {
- if (addSpace)
- OS << ' ';
- addSpace = true;
- switch (addrspace) {
+ LangAS addrspace = getAddressSpace();
+ if (addrspace != LangAS::Default) {
+ if (addrspace != LangAS::opencl_private) {
+ if (addSpace)
+ OS << ' ';
+ addSpace = true;
+ switch (addrspace) {
case LangAS::opencl_global:
OS << "__global";
break;
case LangAS::opencl_local:
OS << "__local";
break;
+ case LangAS::opencl_private:
+ break;
case LangAS::opencl_constant:
case LangAS::cuda_constant:
OS << "__constant";
@@ -1685,10 +1673,10 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
OS << "__shared";
break;
default:
- assert(addrspace >= LangAS::FirstTargetAddressSpace);
OS << "__attribute__((address_space(";
- OS << addrspace - LangAS::FirstTargetAddressSpace;
+ OS << toTargetAddressSpace(addrspace);
OS << ")))";
+ }
}
}
if (Qualifiers::GC gc = getObjCGCAttr()) {
diff --git a/lib/AST/VTTBuilder.cpp b/lib/AST/VTTBuilder.cpp
index 53461ebbb812..b946f10105f4 100644
--- a/lib/AST/VTTBuilder.cpp
+++ b/lib/AST/VTTBuilder.cpp
@@ -1,4 +1,4 @@
-//===--- VTTBuilder.cpp - C++ VTT layout builder --------------------------===//
+//===- VTTBuilder.cpp - C++ VTT layout builder ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,12 +14,16 @@
#include "clang/AST/VTTBuilder.h"
#include "clang/AST/ASTContext.h"
-#include "clang/AST/CXXInheritance.h"
+#include "clang/AST/BaseSubobject.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
#include "clang/AST/RecordLayout.h"
-#include "clang/Basic/TargetInfo.h"
-#include "llvm/Support/Format.h"
-#include <algorithm>
-#include <cstdio>
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/Support/Casting.h"
+#include <cassert>
+#include <cstdint>
using namespace clang;
@@ -28,9 +32,9 @@ using namespace clang;
VTTBuilder::VTTBuilder(ASTContext &Ctx,
const CXXRecordDecl *MostDerivedClass,
bool GenerateDefinition)
- : Ctx(Ctx), MostDerivedClass(MostDerivedClass),
- MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)),
- GenerateDefinition(GenerateDefinition) {
+ : Ctx(Ctx), MostDerivedClass(MostDerivedClass),
+ MostDerivedClassLayout(Ctx.getASTRecordLayout(MostDerivedClass)),
+ GenerateDefinition(GenerateDefinition) {
// Lay out this VTT.
LayoutVTT(BaseSubobject(MostDerivedClass, CharUnits::Zero()),
/*BaseIsVirtual=*/false);
@@ -56,7 +60,7 @@ void VTTBuilder::AddVTablePointer(BaseSubobject Base, uint64_t VTableIndex,
void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
const CXXRecordDecl *RD = Base.getBase();
- for (const auto &I : RD->bases()) {
+ for (const auto &I : RD->bases()) {
// Don't layout virtual bases.
if (I.isVirtual())
continue;
diff --git a/lib/AST/VTableBuilder.cpp b/lib/AST/VTableBuilder.cpp
index e60ae33f2e5c..347c516ef6a5 100644
--- a/lib/AST/VTableBuilder.cpp
+++ b/lib/AST/VTableBuilder.cpp
@@ -1079,9 +1079,7 @@ static void
visitAllOverriddenMethods(const CXXMethodDecl *MD, VisitorTy &Visitor) {
assert(MD->isVirtual() && "Method is not virtual!");
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *OverriddenMD = *I;
+ for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
if (!Visitor(OverriddenMD))
continue;
visitAllOverriddenMethods(OverriddenMD, Visitor);
@@ -1329,11 +1327,8 @@ static bool OverridesIndirectMethodInBases(
ItaniumVTableBuilder::PrimaryBasesSetVectorTy &Bases) {
if (Bases.count(MD->getParent()))
return true;
-
- for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
- E = MD->end_overridden_methods(); I != E; ++I) {
- const CXXMethodDecl *OverriddenMD = *I;
-
+
+ for (const CXXMethodDecl *OverriddenMD : MD->overridden_methods()) {
// Check "indirect overriders".
if (OverridesIndirectMethodInBases(OverriddenMD, Bases))
return true;
@@ -2963,6 +2958,9 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
CalculateVtordispAdjustment(FinalOverrider, ThisOffset,
ThisAdjustmentOffset);
+ unsigned VBIndex =
+ LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
+
if (OverriddenMD) {
// If MD overrides anything in this vftable, we need to update the
// entries.
@@ -2975,6 +2973,8 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
MethodInfo &OverriddenMethodInfo = OverriddenMDIterator->second;
+ VBIndex = OverriddenMethodInfo.VBTableIndex;
+
// Let's check if the overrider requires any return adjustments.
// We must create a new slot if the MD's return type is not trivially
// convertible to the OverriddenMD's one.
@@ -2987,8 +2987,7 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
if (!ReturnAdjustingThunk) {
// No return adjustment needed - just replace the overridden method info
// with the current info.
- MethodInfo MI(OverriddenMethodInfo.VBTableIndex,
- OverriddenMethodInfo.VFTableIndex);
+ MethodInfo MI(VBIndex, OverriddenMethodInfo.VFTableIndex);
MethodInfoMap.erase(OverriddenMDIterator);
assert(!MethodInfoMap.count(MD) &&
@@ -3015,8 +3014,6 @@ void VFTableBuilder::AddMethods(BaseSubobject Base, unsigned BaseDepth,
// If we got here, MD is a method not seen in any of the sub-bases or
// it requires return adjustment. Insert the method info for this method.
- unsigned VBIndex =
- LastVBase ? VTables.getVBTableIndex(MostDerivedClass, LastVBase) : 0;
MethodInfo MI(VBIndex,
HasRTTIComponent ? Components.size() - 1 : Components.size(),
ReturnAdjustingThunk);
diff --git a/lib/ASTMatchers/ASTMatchFinder.cpp b/lib/ASTMatchers/ASTMatchFinder.cpp
index 49b15ee68500..02aee4b46ddd 100644
--- a/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -734,7 +734,10 @@ private:
BoundNodesTreeBuilder *Builder) {
const Type *const CanonicalType =
ActiveASTContext->getCanonicalType(TypeNode);
- for (const TypedefNameDecl *Alias : TypeAliases.lookup(CanonicalType)) {
+ auto Aliases = TypeAliases.find(CanonicalType);
+ if (Aliases == TypeAliases.end())
+ return false;
+ for (const TypedefNameDecl *Alias : Aliases->second) {
BoundNodesTreeBuilder Result(*Builder);
if (Matcher.matches(*Alias, this, &Result)) {
*Builder = std::move(Result);
diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp
index f0bfbf9e32d8..0bcdd8e32804 100644
--- a/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -1,4 +1,4 @@
-//===--- ASTMatchersInternal.cpp - Structural query framework -------------===//
+//===- ASTMatchersInternal.cpp - Structural query framework ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,11 +11,30 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <string>
+#include <utility>
+#include <vector>
namespace clang {
namespace ast_matchers {
@@ -40,7 +59,6 @@ bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
BoundNodesTreeBuilder *Builder,
ArrayRef<DynTypedMatcher> InnerMatchers);
-
void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
if (Bindings.empty())
Bindings.push_back(BoundNodesMap());
@@ -51,7 +69,7 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
namespace {
-typedef bool (*VariadicOperatorFunction)(
+using VariadicOperatorFunction = bool (*)(
const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
@@ -100,20 +118,22 @@ public:
TrueMatcherImpl() {
Retain(); // Reference count will never become zero.
}
+
bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
BoundNodesTreeBuilder *) const override {
return true;
}
};
-static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
-} // namespace
+} // namespace
+
+static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
DynTypedMatcher DynTypedMatcher::constructVariadic(
DynTypedMatcher::VariadicOperator Op,
ast_type_traits::ASTNodeKind SupportedKind,
std::vector<DynTypedMatcher> InnerMatchers) {
- assert(InnerMatchers.size() > 0 && "Array must not be empty.");
+ assert(!InnerMatchers.empty() && "Array must not be empty.");
assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
[SupportedKind](const DynTypedMatcher &M) {
return M.canConvertTo(SupportedKind);
@@ -314,9 +334,7 @@ HasNameMatcher::HasNameMatcher(std::vector<std::string> N)
#endif
}
-namespace {
-
-bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
+static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
StringRef Name = FullName;
if (!Name.endswith(Suffix))
return false;
@@ -330,7 +348,8 @@ bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) {
return true;
}
-StringRef getNodeName(const NamedDecl &Node, llvm::SmallString<128> &Scratch) {
+static StringRef getNodeName(const NamedDecl &Node,
+ llvm::SmallString<128> &Scratch) {
// Simple name.
if (Node.getIdentifier())
return Node.getName();
@@ -346,7 +365,8 @@ StringRef getNodeName(const NamedDecl &Node, llvm::SmallString<128> &Scratch) {
return "(anonymous)";
}
-StringRef getNodeName(const RecordDecl &Node, llvm::SmallString<128> &Scratch) {
+static StringRef getNodeName(const RecordDecl &Node,
+ llvm::SmallString<128> &Scratch) {
if (Node.getIdentifier()) {
return Node.getName();
}
@@ -354,11 +374,12 @@ StringRef getNodeName(const RecordDecl &Node, llvm::SmallString<128> &Scratch) {
return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch);
}
-StringRef getNodeName(const NamespaceDecl &Node,
- llvm::SmallString<128> &Scratch) {
+static StringRef getNodeName(const NamespaceDecl &Node,
+ llvm::SmallString<128> &Scratch) {
return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName();
}
+namespace {
class PatternSet {
public:
@@ -397,10 +418,11 @@ private:
StringRef P;
bool IsFullyQualified;
};
+
llvm::SmallVector<Pattern, 8> Patterns;
};
-} // namespace
+} // namespace
bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
assert(UseUnqualifiedMatch);
@@ -504,5 +526,282 @@ bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
}
} // end namespace internal
+
+const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl>
+ translationUnitDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
+ typedefNameDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
+ typeAliasTemplateDecl;
+const internal::VariadicAllOfMatcher<Decl> decl;
+const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl>
+ linkageSpecDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl>
+ namespaceAliasDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, RecordDecl> recordDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXRecordDecl> cxxRecordDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ClassTemplateDecl>
+ classTemplateDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl,
+ ClassTemplateSpecializationDecl>
+ classTemplateSpecializationDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, DeclaratorDecl>
+ declaratorDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ParmVarDecl> parmVarDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, AccessSpecDecl>
+ accessSpecDecl;
+const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer;
+const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument;
+const internal::VariadicAllOfMatcher<TemplateName> templateName;
+const internal::VariadicDynCastAllOfMatcher<Decl, NonTypeTemplateParmDecl>
+ nonTypeTemplateParmDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl>
+ templateTypeParmDecl;
+const internal::VariadicAllOfMatcher<QualType> qualType;
+const internal::VariadicAllOfMatcher<Type> type;
+const internal::VariadicAllOfMatcher<TypeLoc> typeLoc;
+const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
+ unaryExprOrTypeTraitExpr;
+const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXConstructorDecl>
+ cxxConstructorDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXDestructorDecl>
+ cxxDestructorDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl>
+ enumConstantDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
+ cxxConversionDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, FunctionDecl> functionDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, FunctionTemplateDecl>
+ functionTemplateDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, FriendDecl> friendDecl;
+const internal::VariadicAllOfMatcher<Stmt> stmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DeclStmt> declStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, MemberExpr> memberExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CallExpr> callExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXMemberCallExpr>
+ cxxMemberCallExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCMessageExpr>
+ objcMessageExpr;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCInterfaceDecl>
+ objcInterfaceDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCImplementationDecl>
+ objcImplementationDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCProtocolDecl>
+ objcProtocolDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryDecl>
+ objcCategoryDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCCategoryImplDecl>
+ objcCategoryImplDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCMethodDecl>
+ objcMethodDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCIvarDecl> objcIvarDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, ObjCPropertyDecl>
+ objcPropertyDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtThrowStmt>
+ objcThrowStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtTryStmt> objcTryStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtCatchStmt>
+ objcCatchStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ObjCAtFinallyStmt>
+ objcFinallyStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups>
+ exprWithCleanups;
+const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStdInitializerListExpr>
+ cxxStdInitializerListExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr>
+ implicitValueInitExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr>
+ substNonTypeTemplateParmExpr;
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl>
+ usingDirectiveDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, UnresolvedLookupExpr>
+ unresolvedLookupExpr;
+const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingValueDecl>
+ unresolvedUsingValueDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, UnresolvedUsingTypenameDecl>
+ unresolvedUsingTypenameDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ParenExpr> parenExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstructExpr>
+ cxxConstructExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXUnresolvedConstructExpr>
+ cxxUnresolvedConstructExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBindTemporaryExpr>
+ cxxBindTemporaryExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, MaterializeTemporaryExpr>
+ materializeTemporaryExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ArraySubscriptExpr>
+ arraySubscriptExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDefaultArgExpr>
+ cxxDefaultArgExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXOperatorCallExpr>
+ cxxOperatorCallExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, Expr> expr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DeclRefExpr> declRefExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, IfStmt> ifStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ForStmt> forStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt>
+ cxxForRangeStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchStmt> switchStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, NullStmt> nullStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXBoolLiteralExpr>
+ cxxBoolLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, StringLiteral> stringLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CharacterLiteral>
+ characterLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, IntegerLiteral>
+ integerLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> floatLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
+ userDefinedLiteral;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
+ compoundLiteralExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
+ cxxNullPtrLiteralExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryOperator>
+ binaryOperator;
+const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryOperator> unaryOperator;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ConditionalOperator>
+ conditionalOperator;
+const internal::VariadicDynCastAllOfMatcher<Stmt, BinaryConditionalOperator>
+ binaryConditionalOperator;
+const internal::VariadicDynCastAllOfMatcher<Stmt, OpaqueValueExpr>
+ opaqueValueExpr;
+const internal::VariadicDynCastAllOfMatcher<Decl, StaticAssertDecl>
+ staticAssertDecl;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXReinterpretCastExpr>
+ cxxReinterpretCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXStaticCastExpr>
+ cxxStaticCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDynamicCastExpr>
+ cxxDynamicCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXConstCastExpr>
+ cxxConstCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CStyleCastExpr>
+ cStyleCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ExplicitCastExpr>
+ explicitCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitCastExpr>
+ implicitCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXFunctionalCastExpr>
+ cxxFunctionalCastExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTemporaryObjectExpr>
+ cxxTemporaryObjectExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, PredefinedExpr>
+ predefinedExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DesignatedInitExpr>
+ designatedInitExpr;
+const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ eachOf = {internal::DynTypedMatcher::VO_EachOf};
+const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ anyOf = {internal::DynTypedMatcher::VO_AnyOf};
+const internal::VariadicOperatorMatcherFunc<
+ 2, std::numeric_limits<unsigned>::max()>
+ allOf = {internal::DynTypedMatcher::VO_AllOf};
+const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef,
+ internal::hasAnyNameFunc>
+ hasAnyName = {};
+const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> has = {};
+const internal::ArgumentAdaptingMatcherFunc<internal::HasDescendantMatcher>
+ hasDescendant = {};
+const internal::ArgumentAdaptingMatcherFunc<internal::ForEachMatcher> forEach =
+ {};
+const internal::ArgumentAdaptingMatcherFunc<internal::ForEachDescendantMatcher>
+ forEachDescendant = {};
+const internal::ArgumentAdaptingMatcherFunc<
+ internal::HasParentMatcher,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
+ hasParent = {};
+const internal::ArgumentAdaptingMatcherFunc<
+ internal::HasAncestorMatcher,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>,
+ internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>>
+ hasAncestor = {};
+const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
+ internal::DynTypedMatcher::VO_UnaryNot};
+const internal::VariadicAllOfMatcher<NestedNameSpecifier> nestedNameSpecifier;
+const internal::VariadicAllOfMatcher<NestedNameSpecifierLoc>
+ nestedNameSpecifierLoc;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr>
+ cudaKernelCallExpr;
+const AstTypeMatcher<BuiltinType> builtinType;
+const AstTypeMatcher<ArrayType> arrayType;
+const AstTypeMatcher<ComplexType> complexType;
+const AstTypeMatcher<ConstantArrayType> constantArrayType;
+const AstTypeMatcher<DependentSizedArrayType> dependentSizedArrayType;
+const AstTypeMatcher<IncompleteArrayType> incompleteArrayType;
+const AstTypeMatcher<VariableArrayType> variableArrayType;
+const AstTypeMatcher<AtomicType> atomicType;
+const AstTypeMatcher<AutoType> autoType;
+const AstTypeMatcher<FunctionType> functionType;
+const AstTypeMatcher<FunctionProtoType> functionProtoType;
+const AstTypeMatcher<ParenType> parenType;
+const AstTypeMatcher<BlockPointerType> blockPointerType;
+const AstTypeMatcher<MemberPointerType> memberPointerType;
+const AstTypeMatcher<PointerType> pointerType;
+const AstTypeMatcher<ObjCObjectPointerType> objcObjectPointerType;
+const AstTypeMatcher<ReferenceType> referenceType;
+const AstTypeMatcher<LValueReferenceType> lValueReferenceType;
+const AstTypeMatcher<RValueReferenceType> rValueReferenceType;
+const AstTypeMatcher<TypedefType> typedefType;
+const AstTypeMatcher<EnumType> enumType;
+const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
+const AstTypeMatcher<UnaryTransformType> unaryTransformType;
+const AstTypeMatcher<RecordType> recordType;
+const AstTypeMatcher<TagType> tagType;
+const AstTypeMatcher<ElaboratedType> elaboratedType;
+const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
+const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
+const AstTypeMatcher<InjectedClassNameType> injectedClassNameType;
+const AstTypeMatcher<DecayedType> decayedType;
+AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasElementType,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(ArrayType,
+ ComplexType));
+AST_TYPELOC_TRAVERSE_MATCHER_DEF(hasValueType,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(AtomicType));
+AST_TYPELOC_TRAVERSE_MATCHER_DEF(
+ pointee,
+ AST_POLYMORPHIC_SUPPORTED_TYPES(BlockPointerType, MemberPointerType,
+ PointerType, ReferenceType));
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index c557ff162691..af90e2c7eca1 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -1,4 +1,4 @@
-//===--- Marshallers.h - Generic matcher function marshallers ---*- C++ -*-===//
+//===- Marshallers.h - Generic matcher function marshallers -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,7 +6,7 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-///
+//
/// \file
/// \brief Functions templates and classes to wrap matcher construct functions.
///
@@ -14,18 +14,33 @@
/// marshalling layer on top of matcher construct functions.
/// These are used by the registry to export all marshaller constructors with
/// the same generic interface.
-///
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
#define LLVM_CLANG_LIB_ASTMATCHERS_DYNAMIC_MARSHALLERS_H
-#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "clang/Basic/AttrKinds.h"
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
+#include <cassert>
+#include <cstddef>
+#include <iterator>
+#include <limits>
+#include <memory>
#include <string>
+#include <utility>
+#include <vector>
namespace clang {
namespace ast_matchers {
@@ -41,9 +56,11 @@ template <class T> struct ArgTypeTraits<const T &> : public ArgTypeTraits<T> {
template <> struct ArgTypeTraits<std::string> {
static bool is(const VariantValue &Value) { return Value.isString(); }
+
static const std::string &get(const VariantValue &Value) {
return Value.getString();
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_String);
}
@@ -53,13 +70,15 @@ template <>
struct ArgTypeTraits<StringRef> : public ArgTypeTraits<std::string> {
};
-template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
+template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T>> {
static bool is(const VariantValue &Value) {
return Value.isMatcher() && Value.getMatcher().hasTypedMatcher<T>();
}
+
static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
return Value.getMatcher().getTypedMatcher<T>();
}
+
static ArgKind getKind() {
return ArgKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
}
@@ -67,9 +86,11 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
template <> struct ArgTypeTraits<bool> {
static bool is(const VariantValue &Value) { return Value.isBoolean(); }
+
static bool get(const VariantValue &Value) {
return Value.getBoolean();
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_Boolean);
}
@@ -77,9 +98,11 @@ template <> struct ArgTypeTraits<bool> {
template <> struct ArgTypeTraits<double> {
static bool is(const VariantValue &Value) { return Value.isDouble(); }
+
static double get(const VariantValue &Value) {
return Value.getDouble();
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_Double);
}
@@ -87,9 +110,11 @@ template <> struct ArgTypeTraits<double> {
template <> struct ArgTypeTraits<unsigned> {
static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
+
static unsigned get(const VariantValue &Value) {
return Value.getUnsigned();
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_Unsigned);
}
@@ -97,42 +122,45 @@ template <> struct ArgTypeTraits<unsigned> {
template <> struct ArgTypeTraits<attr::Kind> {
private:
- static attr::Kind getAttrKind(llvm::StringRef AttrKind) {
- return llvm::StringSwitch<attr::Kind>(AttrKind)
+ static Optional<attr::Kind> getAttrKind(llvm::StringRef AttrKind) {
+ return llvm::StringSwitch<Optional<attr::Kind>>(AttrKind)
#define ATTR(X) .Case("attr::" #X, attr:: X)
#include "clang/Basic/AttrList.inc"
- .Default(attr::Kind(-1));
+ .Default(llvm::None);
}
+
public:
static bool is(const VariantValue &Value) {
- return Value.isString() &&
- getAttrKind(Value.getString()) != attr::Kind(-1);
+ return Value.isString() && getAttrKind(Value.getString());
}
+
static attr::Kind get(const VariantValue &Value) {
- return getAttrKind(Value.getString());
+ return *getAttrKind(Value.getString());
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_String);
}
};
-template <> struct ArgTypeTraits<clang::CastKind> {
+template <> struct ArgTypeTraits<CastKind> {
private:
- static clang::CastKind getCastKind(llvm::StringRef AttrKind) {
- return llvm::StringSwitch<clang::CastKind>(AttrKind)
+ static Optional<CastKind> getCastKind(llvm::StringRef AttrKind) {
+ return llvm::StringSwitch<Optional<CastKind>>(AttrKind)
#define CAST_OPERATION(Name) .Case( #Name, CK_##Name)
#include "clang/AST/OperationKinds.def"
- .Default(CK_Invalid);
+ .Default(llvm::None);
}
public:
static bool is(const VariantValue &Value) {
- return Value.isString() &&
- getCastKind(Value.getString()) != CK_Invalid;
+ return Value.isString() && getCastKind(Value.getString());
}
- static clang::CastKind get(const VariantValue &Value) {
- return getCastKind(Value.getString());
+
+ static CastKind get(const VariantValue &Value) {
+ return *getCastKind(Value.getString());
}
+
static ArgKind getKind() {
return ArgKind(ArgKind::AK_String);
}
@@ -144,7 +172,8 @@ public:
/// arguments, and various other methods for type introspection.
class MatcherDescriptor {
public:
- virtual ~MatcherDescriptor() {}
+ virtual ~MatcherDescriptor() = default;
+
virtual VariantMatcher create(SourceRange NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error) const = 0;
@@ -201,11 +230,11 @@ inline bool isRetKindConvertibleTo(
/// their types, unpacking them and calling the underlying function.
class FixedArgCountMatcherDescriptor : public MatcherDescriptor {
public:
- typedef VariantMatcher (*MarshallerType)(void (*Func)(),
- StringRef MatcherName,
- SourceRange NameRange,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
+ using MarshallerType = VariantMatcher (*)(void (*Func)(),
+ StringRef MatcherName,
+ SourceRange NameRange,
+ ArrayRef<ParserValue> Args,
+ Diagnostics *Error);
/// \param Marshaller Function to unpack the arguments and call \c Func
/// \param Func Matcher construct function. This is the function that
@@ -229,10 +258,12 @@ public:
bool isVariadic() const override { return false; }
unsigned getNumArgs() const override { return ArgKinds.size(); }
+
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ArgKinds[ArgNo]);
}
+
bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
@@ -303,14 +334,14 @@ struct BuildReturnTypeVector {
};
template <typename T>
-struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T> > {
+struct BuildReturnTypeVector<ast_matchers::internal::Matcher<T>> {
static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
}
};
template <typename T>
-struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T> > {
+struct BuildReturnTypeVector<ast_matchers::internal::BindableMatcher<T>> {
static void build(std::vector<ast_type_traits::ASTNodeKind> &RetTypes) {
RetTypes.push_back(ast_type_traits::ASTNodeKind::getFromNodeKind<T>());
}
@@ -326,7 +357,8 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
bool HasError = false;
for (size_t i = 0, e = Args.size(); i != e; ++i) {
- typedef ArgTypeTraits<ArgT> ArgTraits;
+ using ArgTraits = ArgTypeTraits<ArgT>;
+
const ParserValue &Arg = Args[i];
const VariantValue &Value = Arg.Value;
if (!ArgTraits::is(Value)) {
@@ -360,10 +392,10 @@ variadicMatcherDescriptor(StringRef MatcherName, SourceRange NameRange,
/// object file.
class VariadicFuncMatcherDescriptor : public MatcherDescriptor {
public:
- typedef VariantMatcher (*RunFunc)(StringRef MatcherName,
- SourceRange NameRange,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error);
+ using RunFunc = VariantMatcher (*)(StringRef MatcherName,
+ SourceRange NameRange,
+ ArrayRef<ParserValue> Args,
+ Diagnostics *Error);
template <typename ResultT, typename ArgT,
ResultT (*F)(ArrayRef<const ArgT *>)>
@@ -384,10 +416,12 @@ public:
bool isVariadic() const override { return true; }
unsigned getNumArgs() const override { return 0; }
+
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ArgsKind);
}
+
bool isConvertibleTo(
ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
@@ -458,7 +492,7 @@ static VariantMatcher matcherMarshall0(void (*Func)(), StringRef MatcherName,
SourceRange NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error) {
- typedef ReturnType (*FuncType)();
+ using FuncType = ReturnType (*)();
CHECK_ARG_COUNT(0);
return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)());
}
@@ -469,7 +503,7 @@ static VariantMatcher matcherMarshall1(void (*Func)(), StringRef MatcherName,
SourceRange NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error) {
- typedef ReturnType (*FuncType)(ArgType1);
+ using FuncType = ReturnType (*)(ArgType1);
CHECK_ARG_COUNT(1);
CHECK_ARG_TYPE(0, ArgType1);
return outvalueToVariantMatcher(reinterpret_cast<FuncType>(Func)(
@@ -482,7 +516,7 @@ static VariantMatcher matcherMarshall2(void (*Func)(), StringRef MatcherName,
SourceRange NameRange,
ArrayRef<ParserValue> Args,
Diagnostics *Error) {
- typedef ReturnType (*FuncType)(ArgType1, ArgType2);
+ using FuncType = ReturnType (*)(ArgType1, ArgType2);
CHECK_ARG_COUNT(2);
CHECK_ARG_TYPE(0, ArgType1);
CHECK_ARG_TYPE(1, ArgType2);
@@ -507,8 +541,8 @@ public:
}
private:
- typedef ast_matchers::internal::ArgumentAdaptingMatcherFunc<
- ArgumentAdapterT, FromTypes, ToTypes> AdaptativeFunc;
+ using AdaptativeFunc = ast_matchers::internal::ArgumentAdaptingMatcherFunc<
+ ArgumentAdapterT, FromTypes, ToTypes>;
/// \brief End case for the recursion
static void collect(ast_matchers::internal::EmptyTypeList) {}
@@ -534,7 +568,7 @@ public:
: Overloads(std::make_move_iterator(Callbacks.begin()),
std::make_move_iterator(Callbacks.end())) {}
- ~OverloadedMatcherDescriptor() override {}
+ ~OverloadedMatcherDescriptor() override = default;
VariantMatcher create(SourceRange NameRange,
ArrayRef<ParserValue> Args,
@@ -604,7 +638,8 @@ private:
/// \brief Variadic operator marshaller function.
class VariadicOperatorMatcherDescriptor : public MatcherDescriptor {
public:
- typedef DynTypedMatcher::VariadicOperator VarOp;
+ using VarOp = DynTypedMatcher::VariadicOperator;
+
VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount,
VarOp Op, StringRef MatcherName)
: MinCount(MinCount), MaxCount(MaxCount), Op(Op),
@@ -615,7 +650,9 @@ public:
Diagnostics *Error) const override {
if (Args.size() < MinCount || MaxCount < Args.size()) {
const std::string MaxStr =
- (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
+ (MaxCount == std::numeric_limits<unsigned>::max() ? ""
+ : Twine(MaxCount))
+ .str();
Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
<< ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
return VariantMatcher();
@@ -637,10 +674,12 @@ public:
bool isVariadic() const override { return true; }
unsigned getNumArgs() const override { return 0; }
+
void getArgKinds(ast_type_traits::ASTNodeKind ThisKind, unsigned ArgNo,
std::vector<ArgKind> &Kinds) const override {
Kinds.push_back(ThisKind);
}
+
bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, unsigned *Specificity,
ast_type_traits::ASTNodeKind *LeastDerivedKind) const override {
if (Specificity)
@@ -649,6 +688,7 @@ public:
*LeastDerivedKind = Kind;
return true;
}
+
bool isPolymorphic() const override { return true; }
private:
diff --git a/lib/ASTMatchers/Dynamic/Parser.cpp b/lib/ASTMatchers/Dynamic/Parser.cpp
index f5bd29668995..89e1a2695860 100644
--- a/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -1,4 +1,4 @@
-//===--- Parser.cpp - Matcher expression parser -----*- C++ -*-===//
+//===- Parser.cpp - Matcher expression parser -----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,11 +13,21 @@
//===----------------------------------------------------------------------===//
#include "clang/ASTMatchers/Dynamic/Parser.h"
+#include "clang/ASTMatchers/ASTMatchersInternal.h"
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <cstddef>
+#include <cstdlib>
#include <string>
+#include <utility>
#include <vector>
namespace clang {
@@ -43,10 +53,10 @@ struct Parser::TokenInfo {
/// \brief Some known identifiers.
static const char* const ID_Bind;
- TokenInfo() : Text(), Kind(TK_Eof), Range(), Value() {}
+ TokenInfo() = default;
StringRef Text;
- TokenKind Kind;
+ TokenKind Kind = TK_Eof;
SourceRange Range;
VariantValue Value;
};
@@ -57,14 +67,13 @@ const char* const Parser::TokenInfo::ID_Bind = "bind";
class Parser::CodeTokenizer {
public:
explicit CodeTokenizer(StringRef MatcherCode, Diagnostics *Error)
- : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error),
- CodeCompletionLocation(nullptr) {
+ : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error) {
NextToken = getNextToken();
}
CodeTokenizer(StringRef MatcherCode, Diagnostics *Error,
unsigned CodeCompletionOffset)
- : Code(MatcherCode), StartOfLine(MatcherCode), Line(1), Error(Error),
+ : Code(MatcherCode), StartOfLine(MatcherCode), Error(Error),
CodeCompletionLocation(MatcherCode.data() + CodeCompletionOffset) {
NextToken = getNextToken();
}
@@ -138,7 +147,7 @@ private:
if (isAlphanumeric(Code[0])) {
// Parse an identifier
size_t TokenLength = 1;
- while (1) {
+ while (true) {
// A code completion location in/immediately after an identifier will
// cause the portion of the identifier before the code completion
// location to become a code completion token.
@@ -283,22 +292,22 @@ private:
StringRef Code;
StringRef StartOfLine;
- unsigned Line;
+ unsigned Line = 1;
Diagnostics *Error;
TokenInfo NextToken;
- const char *CodeCompletionLocation;
+ const char *CodeCompletionLocation = nullptr;
};
-Parser::Sema::~Sema() {}
+Parser::Sema::~Sema() = default;
std::vector<ArgKind> Parser::Sema::getAcceptedCompletionTypes(
llvm::ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
- return std::vector<ArgKind>();
+ return {};
}
std::vector<MatcherCompletion>
Parser::Sema::getMatcherCompletions(llvm::ArrayRef<ArgKind> AcceptedTypes) {
- return std::vector<MatcherCompletion>();
+ return {};
}
struct Parser::ScopedContextEntry {
@@ -384,7 +393,7 @@ bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
EndToken = Tokenizer->consumeNextToken();
break;
}
- if (Args.size() > 0) {
+ if (!Args.empty()) {
// We must find a , token to continue.
const TokenInfo CommaToken = Tokenizer->consumeNextToken();
if (CommaToken.Kind != TokenInfo::TK_Comma) {
@@ -558,7 +567,7 @@ Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
: Tokenizer(Tokenizer), S(S ? S : &*DefaultRegistrySema),
NamedValues(NamedValues), Error(Error) {}
-Parser::RegistrySema::~RegistrySema() {}
+Parser::RegistrySema::~RegistrySema() = default;
llvm::Optional<MatcherCtor>
Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
@@ -640,6 +649,6 @@ Parser::parseMatcherExpression(StringRef Code, Sema *S,
return Result;
}
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
+} // namespace dynamic
+} // namespace ast_matchers
+} // namespace clang
diff --git a/lib/ASTMatchers/Dynamic/Registry.cpp b/lib/ASTMatchers/Dynamic/Registry.cpp
index 031ceb320306..2b7bb7a2120d 100644
--- a/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -1,37 +1,49 @@
-//===--- Registry.cpp - Matcher registry -------------------------===//
+//===- Registry.cpp - Matcher registry ------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
-//===------------------------------------------------------------===//
-///
+//===----------------------------------------------------------------------===//
+//
/// \file
/// \brief Registry map populated at static initialization time.
-///
-//===------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
#include "clang/ASTMatchers/Dynamic/Registry.h"
#include "Marshallers.h"
+#include "clang/AST/ASTTypeTraits.h"
#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/Dynamic/Diagnostics.h"
+#include "clang/ASTMatchers/Dynamic/VariantValue.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <iterator>
+#include <memory>
#include <set>
+#include <string>
#include <utility>
+#include <vector>
using namespace clang::ast_type_traits;
namespace clang {
namespace ast_matchers {
namespace dynamic {
+
namespace {
using internal::MatcherDescriptor;
-typedef llvm::StringMap<std::unique_ptr<const MatcherDescriptor>> ConstructorMap;
+using ConstructorMap = llvm::StringMap<std::unique_ptr<const MatcherDescriptor>>;
+
class RegistryMaps {
public:
RegistryMaps();
@@ -46,6 +58,8 @@ private:
ConstructorMap Constructors;
};
+} // namespace
+
void RegistryMaps::registerMatcher(
StringRef MatcherName, std::unique_ptr<MatcherDescriptor> Callback) {
assert(Constructors.find(MatcherName) == Constructors.end());
@@ -74,7 +88,7 @@ void RegistryMaps::registerMatcher(
MATCHER_OVERLOAD_ENTRY(name, 0), \
MATCHER_OVERLOAD_ENTRY(name, 1)}; \
REGISTER_MATCHER_OVERLOAD(name); \
- } while (0)
+ } while (false)
/// \brief Generate a registry map with all the known matchers.
RegistryMaps::RegistryMaps() {
@@ -196,6 +210,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(forEachArgumentWithParam);
REGISTER_MATCHER(forEachConstructorInitializer);
REGISTER_MATCHER(forEachDescendant);
+ REGISTER_MATCHER(forEachOverridden);
REGISTER_MATCHER(forEachSwitchCase);
REGISTER_MATCHER(forField);
REGISTER_MATCHER(forFunction);
@@ -219,6 +234,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasAnyUsingShadowDecl);
REGISTER_MATCHER(hasArgument);
REGISTER_MATCHER(hasArgumentOfType);
+ REGISTER_MATCHER(hasArraySize);
REGISTER_MATCHER(hasAttr);
REGISTER_MATCHER(hasAutomaticStorageDuration);
REGISTER_MATCHER(hasBase);
@@ -233,6 +249,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasDeclaration);
REGISTER_MATCHER(hasDeclContext);
REGISTER_MATCHER(hasDeducedType);
+ REGISTER_MATCHER(hasDefaultArgument);
+ REGISTER_MATCHER(hasDefinition);
REGISTER_MATCHER(hasDescendant);
REGISTER_MATCHER(hasDestinationType);
REGISTER_MATCHER(hasDynamicExceptionSpec);
@@ -301,6 +319,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(isAnonymous);
REGISTER_MATCHER(isAnyCharacter);
REGISTER_MATCHER(isAnyPointer);
+ REGISTER_MATCHER(isArray);
REGISTER_MATCHER(isArrow);
REGISTER_MATCHER(isBaseInitializer);
REGISTER_MATCHER(isBitField);
@@ -355,6 +374,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(labelDecl);
REGISTER_MATCHER(labelStmt);
REGISTER_MATCHER(lambdaExpr);
+ REGISTER_MATCHER(linkageSpecDecl);
REGISTER_MATCHER(lValueReferenceType);
REGISTER_MATCHER(matchesName);
REGISTER_MATCHER(matchesSelector);
@@ -372,7 +392,11 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(nullStmt);
REGISTER_MATCHER(numSelectorArgs);
REGISTER_MATCHER(ofClass);
+ REGISTER_MATCHER(objcCatchStmt);
REGISTER_MATCHER(objcCategoryDecl);
+ REGISTER_MATCHER(objcCategoryImplDecl);
+ REGISTER_MATCHER(objcFinallyStmt);
+ REGISTER_MATCHER(objcImplementationDecl);
REGISTER_MATCHER(objcInterfaceDecl);
REGISTER_MATCHER(objcIvarDecl);
REGISTER_MATCHER(objcMessageExpr);
@@ -380,6 +404,8 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(objcObjectPointerType);
REGISTER_MATCHER(objcPropertyDecl);
REGISTER_MATCHER(objcProtocolDecl);
+ REGISTER_MATCHER(objcThrowStmt);
+ REGISTER_MATCHER(objcTryStmt);
REGISTER_MATCHER(on);
REGISTER_MATCHER(onImplicitObjectArgument);
REGISTER_MATCHER(opaqueValueExpr);
@@ -450,12 +476,10 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(withInitializer);
}
-RegistryMaps::~RegistryMaps() {}
+RegistryMaps::~RegistryMaps() = default;
static llvm::ManagedStatic<RegistryMaps> RegistryData;
-} // anonymous namespace
-
// static
llvm::Optional<MatcherCtor> Registry::lookupMatcherCtor(StringRef MatcherName) {
auto it = RegistryData->constructors().find(MatcherName);
@@ -464,10 +488,8 @@ llvm::Optional<MatcherCtor> Registry::lookupMatcherCtor(StringRef MatcherName) {
: it->second.get();
}
-namespace {
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
- const std::set<ASTNodeKind> &KS) {
+static llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const std::set<ASTNodeKind> &KS) {
unsigned Count = 0;
for (std::set<ASTNodeKind>::const_iterator I = KS.begin(), E = KS.end();
I != E; ++I) {
@@ -482,8 +504,6 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
return OS;
}
-} // namespace
-
std::vector<ArgKind> Registry::getAcceptedCompletionTypes(
ArrayRef<std::pair<MatcherCtor, unsigned>> Context) {
ASTNodeKind InitialTypes[] = {
@@ -593,7 +613,6 @@ Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) {
return Completions;
}
-// static
VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
SourceRange NameRange,
ArrayRef<ParserValue> Args,
@@ -601,7 +620,6 @@ VariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
return Ctor->create(NameRange, Args, Error);
}
-// static
VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
SourceRange NameRange,
StringRef BindID,
@@ -621,6 +639,6 @@ VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
return VariantMatcher();
}
-} // namespace dynamic
-} // namespace ast_matchers
-} // namespace clang
+} // namespace dynamic
+} // namespace ast_matchers
+} // namespace clang
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index ec15f34fb231..181edff0a03f 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -12,8 +12,7 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Analysis/AnalysisContext.h"
-#include "BodyFarm.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
@@ -23,6 +22,7 @@
#include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
+#include "clang/Analysis/BodyFarm.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CFGStmtMap.h"
#include "clang/Analysis/Support/BumpVector.h"
@@ -63,33 +63,25 @@ AnalysisDeclContext::AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
}
-AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
- bool addImplicitDtors,
- bool addInitializers,
- bool addTemporaryDtors,
- bool addLifetime,
- bool synthesizeBodies,
- bool addStaticInitBranch,
- bool addCXXNewAllocator,
- CodeInjector *injector)
- : Injector(injector), SynthesizeBodies(synthesizeBodies)
-{
+AnalysisDeclContextManager::AnalysisDeclContextManager(
+ ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
+ bool addInitializers, bool addTemporaryDtors, bool addLifetime,
+ bool addLoopExit, bool synthesizeBodies, bool addStaticInitBranch,
+ bool addCXXNewAllocator, CodeInjector *injector)
+ : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
+ SynthesizeBodies(synthesizeBodies) {
cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
cfgBuildOptions.AddInitializers = addInitializers;
cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
cfgBuildOptions.AddLifetime = addLifetime;
+ cfgBuildOptions.AddLoopExit = addLoopExit;
cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
}
void AnalysisDeclContextManager::clear() { Contexts.clear(); }
-static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) {
- static BodyFarm *BF = new BodyFarm(C, injector);
- return *BF;
-}
-
Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
IsAutosynthesized = false;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -97,8 +89,7 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
Body = CoroBody->getBody();
if (Manager && Manager->synthesizeBodies()) {
- Stmt *SynthesizedBody =
- getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
+ Stmt *SynthesizedBody = Manager->getBodyFarm().getBody(FD);
if (SynthesizedBody) {
Body = SynthesizedBody;
IsAutosynthesized = true;
@@ -109,8 +100,7 @@ Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
Stmt *Body = MD->getBody();
if (Manager && Manager->synthesizeBodies()) {
- Stmt *SynthesizedBody =
- getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
+ Stmt *SynthesizedBody = Manager->getBodyFarm().getBody(MD);
if (SynthesizedBody) {
Body = SynthesizedBody;
IsAutosynthesized = true;
@@ -315,6 +305,8 @@ AnalysisDeclContext *AnalysisDeclContextManager::getContext(const Decl *D) {
return AC.get();
}
+BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
+
const StackFrameContext *
AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
const CFGBlock *Blk, unsigned Idx) {
@@ -608,8 +600,6 @@ AnalysisDeclContext::~AnalysisDeclContext() {
}
}
-AnalysisDeclContextManager::~AnalysisDeclContextManager() {}
-
LocationContext::~LocationContext() {}
LocationContextManager::~LocationContextManager() {
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 59127246105d..e5d3c5ce5bc2 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -12,13 +12,20 @@
//
//===----------------------------------------------------------------------===//
-#include "BodyFarm.h"
+#include "clang/Analysis/BodyFarm.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/Analysis/CodeInjector.h"
+#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "body-farm"
using namespace clang;
@@ -55,7 +62,8 @@ public:
CompoundStmt *makeCompound(ArrayRef<Stmt*>);
/// Create a new DeclRefExpr for the referenced variable.
- DeclRefExpr *makeDeclRefExpr(const VarDecl *D);
+ DeclRefExpr *makeDeclRefExpr(const VarDecl *D,
+ bool RefersToEnclosingVariableOrCapture = false);
/// Create a new UnaryOperator representing a dereference.
UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);
@@ -66,9 +74,19 @@ public:
/// Create an implicit cast to a builtin boolean type.
ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
- // Create an implicit cast for lvalue-to-rvaluate conversions.
+ /// Create an implicit cast for lvalue-to-rvaluate conversions.
ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
+ /// Make RValue out of variable declaration, creating a temporary
+ /// DeclRefExpr in the process.
+ ImplicitCastExpr *
+ makeLvalueToRvalue(const VarDecl *Decl,
+ bool RefersToEnclosingVariableOrCapture = false);
+
+ /// Create an implicit cast of the given type.
+ ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty,
+ CastKind CK = CK_LValueToRValue);
+
/// Create an Objective-C bool literal.
ObjCBoolLiteralExpr *makeObjCBool(bool Val);
@@ -78,6 +96,18 @@ public:
/// Create a Return statement.
ReturnStmt *makeReturn(const Expr *RetVal);
+ /// Create an integer literal expression of the given type.
+ IntegerLiteral *makeIntegerLiteral(uint64_t Value, QualType Ty);
+
+ /// Create a member expression.
+ MemberExpr *makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
+ bool IsArrow = false,
+ ExprValueKind ValueKind = VK_LValue);
+
+ /// Returns a *first* member field of a record declaration with a given name.
+ /// \return an nullptr if no member with such a name exists.
+ ValueDecl *findMemberField(const RecordDecl *RD, StringRef Name);
+
private:
ASTContext &C;
};
@@ -106,16 +136,14 @@ CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation());
}
-DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
- DeclRefExpr *DR =
- DeclRefExpr::Create(/* Ctx = */ C,
- /* QualifierLoc = */ NestedNameSpecifierLoc(),
- /* TemplateKWLoc = */ SourceLocation(),
- /* D = */ const_cast<VarDecl*>(D),
- /* RefersToEnclosingVariableOrCapture = */ false,
- /* NameLoc = */ SourceLocation(),
- /* T = */ D->getType(),
- /* VK = */ VK_LValue);
+DeclRefExpr *ASTMaker::makeDeclRefExpr(
+ const VarDecl *D,
+ bool RefersToEnclosingVariableOrCapture) {
+ QualType Type = D->getType().getNonReferenceType();
+
+ DeclRefExpr *DR = DeclRefExpr::Create(
+ C, NestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D),
+ RefersToEnclosingVariableOrCapture, SourceLocation(), Type, VK_LValue);
return DR;
}
@@ -125,8 +153,25 @@ UnaryOperator *ASTMaker::makeDereference(const Expr *Arg, QualType Ty) {
}
ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
- return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
- const_cast<Expr*>(Arg), nullptr, VK_RValue);
+ return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
+}
+
+ImplicitCastExpr *
+ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
+ bool RefersToEnclosingVariableOrCapture) {
+ QualType Type = Arg->getType().getNonReferenceType();
+ return makeLvalueToRvalue(makeDeclRefExpr(Arg,
+ RefersToEnclosingVariableOrCapture),
+ Type);
+}
+
+ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
+ CastKind CK) {
+ return ImplicitCastExpr::Create(C, Ty,
+ /* CastKind=*/ CK,
+ /* Expr=*/ const_cast<Expr *>(Arg),
+ /* CXXCastPath=*/ nullptr,
+ /* ExprValueKind=*/ VK_RValue);
}
Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
@@ -161,12 +206,259 @@ ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) {
nullptr);
}
+IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) {
+ llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
+ return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
+}
+
+MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
+ bool IsArrow,
+ ExprValueKind ValueKind) {
+
+ DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDecl, AS_public);
+ return MemberExpr::Create(
+ C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
+ SourceLocation(), MemberDecl, FoundDecl,
+ DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
+ /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
+ OK_Ordinary);
+}
+
+ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
+
+ CXXBasePaths Paths(
+ /* FindAmbiguities=*/false,
+ /* RecordPaths=*/false,
+ /* DetectVirtual=*/ false);
+ const IdentifierInfo &II = C.Idents.get(Name);
+ DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
+
+ DeclContextLookupResult Decls = RD->lookup(DeclName);
+ for (NamedDecl *FoundDecl : Decls)
+ if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
+ return cast<ValueDecl>(FoundDecl);
+
+ return nullptr;
+}
+
//===----------------------------------------------------------------------===//
// Creation functions for faux ASTs.
//===----------------------------------------------------------------------===//
typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
+static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
+ const ParmVarDecl *Callback,
+ ArrayRef<Expr *> CallArgs) {
+
+ QualType Ty = Callback->getType();
+ DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
+ CastKind CK;
+ if (Ty->isRValueReferenceType()) {
+ CK = CK_LValueToRValue;
+ } else {
+ assert(Ty->isLValueReferenceType());
+ CK = CK_FunctionToPointerDecay;
+ Ty = C.getPointerType(Ty.getNonReferenceType());
+ }
+
+ return new (C)
+ CallExpr(C, M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK),
+ /*args=*/CallArgs,
+ /*QualType=*/C.VoidTy,
+ /*ExprValueType=*/VK_RValue,
+ /*SourceLocation=*/SourceLocation());
+}
+
+static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
+ const ParmVarDecl *Callback,
+ CXXRecordDecl *CallbackDecl,
+ ArrayRef<Expr *> CallArgs) {
+ assert(CallbackDecl != nullptr);
+ assert(CallbackDecl->isLambda());
+ FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
+ assert(callOperatorDecl != nullptr);
+
+ DeclRefExpr *callOperatorDeclRef =
+ DeclRefExpr::Create(/* Ctx =*/ C,
+ /* QualifierLoc =*/ NestedNameSpecifierLoc(),
+ /* TemplateKWLoc =*/ SourceLocation(),
+ const_cast<FunctionDecl *>(callOperatorDecl),
+ /* RefersToEnclosingVariableOrCapture=*/ false,
+ /* NameLoc =*/ SourceLocation(),
+ /* T =*/ callOperatorDecl->getType(),
+ /* VK =*/ VK_LValue);
+
+ return new (C)
+ CXXOperatorCallExpr(/*AstContext=*/C, OO_Call, callOperatorDeclRef,
+ /*args=*/CallArgs,
+ /*QualType=*/C.VoidTy,
+ /*ExprValueType=*/VK_RValue,
+ /*SourceLocation=*/SourceLocation(), FPOptions());
+}
+
+/// Create a fake body for std::call_once.
+/// Emulates the following function body:
+///
+/// \code
+/// typedef struct once_flag_s {
+/// unsigned long __state = 0;
+/// } once_flag;
+/// template<class Callable>
+/// void call_once(once_flag& o, Callable func) {
+/// if (!o.__state) {
+/// func();
+/// }
+/// o.__state = 1;
+/// }
+/// \endcode
+static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
+ DEBUG(llvm::dbgs() << "Generating body for call_once\n");
+
+ // We need at least two parameters.
+ if (D->param_size() < 2)
+ return nullptr;
+
+ ASTMaker M(C);
+
+ const ParmVarDecl *Flag = D->getParamDecl(0);
+ const ParmVarDecl *Callback = D->getParamDecl(1);
+
+ if (!Callback->getType()->isReferenceType()) {
+ llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
+ return nullptr;
+ }
+ if (!Flag->getType()->isReferenceType()) {
+ llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
+ return nullptr;
+ }
+
+ QualType CallbackType = Callback->getType().getNonReferenceType();
+
+ // Nullable pointer, non-null iff function is a CXXRecordDecl.
+ CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
+ QualType FlagType = Flag->getType().getNonReferenceType();
+ auto *FlagRecordDecl = dyn_cast_or_null<RecordDecl>(FlagType->getAsTagDecl());
+
+ if (!FlagRecordDecl) {
+ DEBUG(llvm::dbgs() << "Flag field is not a record: "
+ << "unknown std::call_once implementation, "
+ << "ignoring the call.\n");
+ return nullptr;
+ }
+
+ // We initially assume libc++ implementation of call_once,
+ // where the once_flag struct has a field `__state_`.
+ ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
+
+ // Otherwise, try libstdc++ implementation, with a field
+ // `_M_once`
+ if (!FlagFieldDecl) {
+ FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
+ }
+
+ if (!FlagFieldDecl) {
+ DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
+ << "std::once_flag struct: unknown std::call_once "
+ << "implementation, ignoring the call.");
+ return nullptr;
+ }
+
+ bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
+ if (CallbackRecordDecl && !isLambdaCall) {
+ DEBUG(llvm::dbgs() << "Not supported: synthesizing body for functors when "
+ << "body farming std::call_once, ignoring the call.");
+ return nullptr;
+ }
+
+ SmallVector<Expr *, 5> CallArgs;
+ const FunctionProtoType *CallbackFunctionType;
+ if (isLambdaCall) {
+
+ // Lambda requires callback itself inserted as a first parameter.
+ CallArgs.push_back(
+ M.makeDeclRefExpr(Callback,
+ /* RefersToEnclosingVariableOrCapture=*/ true));
+ CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
+ ->getType()
+ ->getAs<FunctionProtoType>();
+ } else if (!CallbackType->getPointeeType().isNull()) {
+ CallbackFunctionType =
+ CallbackType->getPointeeType()->getAs<FunctionProtoType>();
+ } else {
+ CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
+ }
+
+ if (!CallbackFunctionType)
+ return nullptr;
+
+ // First two arguments are used for the flag and for the callback.
+ if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
+ DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
+ << "params passed to std::call_once, "
+ << "ignoring the call\n");
+ return nullptr;
+ }
+
+ // All arguments past first two ones are passed to the callback,
+ // and we turn lvalues into rvalues if the argument is not passed by
+ // reference.
+ for (unsigned int ParamIdx = 2; ParamIdx < D->getNumParams(); ParamIdx++) {
+ const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
+ Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
+ if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
+ QualType PTy = PDecl->getType().getNonReferenceType();
+ ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
+ }
+ CallArgs.push_back(ParamExpr);
+ }
+
+ CallExpr *CallbackCall;
+ if (isLambdaCall) {
+
+ CallbackCall = create_call_once_lambda_call(C, M, Callback,
+ CallbackRecordDecl, CallArgs);
+ } else {
+
+ // Function pointer case.
+ CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
+ }
+
+ DeclRefExpr *FlagDecl =
+ M.makeDeclRefExpr(Flag,
+ /* RefersToEnclosingVariableOrCapture=*/true);
+
+
+ MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
+ assert(Deref->isLValue());
+ QualType DerefType = Deref->getType();
+
+ // Negation predicate.
+ UnaryOperator *FlagCheck = new (C) UnaryOperator(
+ /* input=*/
+ M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType,
+ CK_IntegralToBoolean),
+ /* opc=*/ UO_LNot,
+ /* QualType=*/ C.IntTy,
+ /* ExprValueKind=*/ VK_RValue,
+ /* ExprObjectKind=*/ OK_Ordinary, SourceLocation());
+
+ // Create assignment.
+ BinaryOperator *FlagAssignment = M.makeAssignment(
+ Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType),
+ DerefType);
+
+ IfStmt *Out = new (C)
+ IfStmt(C, SourceLocation(),
+ /* IsConstexpr=*/ false,
+ /* init=*/ nullptr,
+ /* var=*/ nullptr,
+ /* cond=*/ FlagCheck,
+ /* then=*/ M.makeCompound({CallbackCall, FlagAssignment}));
+
+ return Out;
+}
+
/// Create a fake body for dispatch_once.
static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
// Check if we have at least two parameters.
@@ -193,8 +485,8 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
// sets it, and calls the block. Basically, an AST dump of:
//
// void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
- // if (!*predicate) {
- // *predicate = 1;
+ // if (*predicate != ~0l) {
+ // *predicate = ~0l;
// block();
// }
// }
@@ -202,22 +494,26 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
ASTMaker M(C);
// (1) Create the call.
- DeclRefExpr *DR = M.makeDeclRefExpr(Block);
- ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
- CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
- SourceLocation());
+ CallExpr *CE = new (C) CallExpr(
+ /*ASTContext=*/C,
+ /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
+ /*args=*/None,
+ /*QualType=*/C.VoidTy,
+ /*ExprValueType=*/VK_RValue,
+ /*SourceLocation=*/SourceLocation());
// (2) Create the assignment to the predicate.
- IntegerLiteral *IL =
- IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
- C.IntTy, SourceLocation());
+ Expr *DoneValue =
+ new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy,
+ VK_RValue, OK_Ordinary, SourceLocation());
+
BinaryOperator *B =
M.makeAssignment(
M.makeDereference(
M.makeLvalueToRvalue(
M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
PredicateTy),
- M.makeIntegralCast(IL, PredicateTy),
+ M.makeIntegralCast(DoneValue, PredicateTy),
PredicateTy);
// (3) Create the compound statement.
@@ -233,14 +529,15 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
PredicateQPtrTy),
PredicateTy),
PredicateTy);
-
- UnaryOperator *UO = new (C) UnaryOperator(LValToRva