aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:06:01 +0000
commit486754660bb926339aefcf012a3f848592babb8b (patch)
treeecdbc446c9876f4f120f701c243373cd3cb43db3 /lib
parent55e6d896ad333f07bb3b1ba487df214fc268a4ab (diff)
downloadsrc-486754660bb926339aefcf012a3f848592babb8b.tar.gz
src-486754660bb926339aefcf012a3f848592babb8b.zip
Vendor import of clang trunk r338150:vendor/clang/clang-trunk-r338150
Notes
Notes: svn path=/vendor/clang/dist/; revision=336815 svn path=/vendor/clang/clang-trunk-r338150/; revision=336816; tag=vendor/clang/clang-trunk-r338150
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp2
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp6
-rw-r--r--lib/ARCMigrate/PlistReporter.cpp3
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp2
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp7
-rw-r--r--lib/ARCMigrate/TransProperties.cpp2
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp4
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp5
-rw-r--r--lib/ARCMigrate/TransformActions.cpp24
-rw-r--r--lib/ARCMigrate/Transforms.cpp4
-rw-r--r--lib/ARCMigrate/Transforms.h12
-rw-r--r--lib/AST/APValue.cpp79
-rw-r--r--lib/AST/ASTContext.cpp1307
-rw-r--r--lib/AST/ASTDiagnostic.cpp2
-rw-r--r--lib/AST/ASTDumper.cpp60
-rw-r--r--lib/AST/ASTImporter.cpp2911
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp535
-rw-r--r--lib/AST/CMakeLists.txt1
-rw-r--r--lib/AST/CXXInheritance.cpp33
-rw-r--r--lib/AST/CommentBriefParser.cpp4
-rw-r--r--lib/AST/CommentLexer.cpp246
-rw-r--r--lib/AST/CommentSema.cpp2
-rw-r--r--lib/AST/ComparisonCategories.cpp211
-rw-r--r--lib/AST/Decl.cpp143
-rw-r--r--lib/AST/DeclBase.cpp278
-rw-r--r--lib/AST/DeclCXX.cpp452
-rw-r--r--lib/AST/DeclFriend.cpp6
-rw-r--r--lib/AST/DeclObjC.cpp142
-rw-r--r--lib/AST/DeclOpenMP.cpp9
-rw-r--r--lib/AST/DeclPrinter.cpp51
-rw-r--r--lib/AST/DeclTemplate.cpp56
-rw-r--r--lib/AST/Expr.cpp130
-rw-r--r--lib/AST/ExprCXX.cpp76
-rw-r--r--lib/AST/ExprClassification.cpp26
-rw-r--r--lib/AST/ExprConstant.cpp1486
-rw-r--r--lib/AST/ExternalASTMerger.cpp45
-rw-r--r--lib/AST/ItaniumCXXABI.cpp63
-rw-r--r--lib/AST/ItaniumMangle.cpp125
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp4
-rw-r--r--lib/AST/MicrosoftMangle.cpp329
-rw-r--r--lib/AST/NSAPI.cpp31
-rw-r--r--lib/AST/NestedNameSpecifier.cpp22
-rw-r--r--lib/AST/ODRHash.cpp212
-rw-r--r--lib/AST/OpenMPClause.cpp4
-rw-r--r--lib/AST/ParentMap.cpp3
-rw-r--r--lib/AST/QualTypeNames.cpp20
-rw-r--r--lib/AST/RawCommentList.cpp110
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp155
-rw-r--r--lib/AST/Stmt.cpp78
-rw-r--r--lib/AST/StmtCXX.cpp10
-rw-r--r--lib/AST/StmtPrinter.cpp253
-rw-r--r--lib/AST/StmtProfile.cpp64
-rw-r--r--lib/AST/TemplateBase.cpp4
-rw-r--r--lib/AST/TemplateName.cpp5
-rw-r--r--lib/AST/Type.cpp702
-rw-r--r--lib/AST/TypeLoc.cpp38
-rw-r--r--lib/AST/TypePrinter.cpp254
-rw-r--r--lib/AST/VTableBuilder.cpp62
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp37
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp40
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h50
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp30
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp16
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp2
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp165
-rw-r--r--lib/Analysis/BodyFarm.cpp68
-rw-r--r--lib/Analysis/CFG.cpp644
-rw-r--r--lib/Analysis/CFGReachabilityAnalysis.cpp11
-rw-r--r--lib/Analysis/CMakeLists.txt1
-rw-r--r--lib/Analysis/CloneDetection.cpp6
-rw-r--r--lib/Analysis/ConstructionContext.cpp184
-rw-r--r--lib/Analysis/Consumed.cpp171
-rw-r--r--lib/Analysis/Dominators.cpp4
-rw-r--r--lib/Analysis/LiveVariables.cpp87
-rw-r--r--lib/Analysis/PostOrderCFGView.cpp7
-rw-r--r--lib/Analysis/PrintfFormatString.cpp114
-rw-r--r--lib/Analysis/ReachableCode.cpp25
-rw-r--r--lib/Analysis/ThreadSafety.cpp547
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp107
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp38
-rw-r--r--lib/Analysis/UninitializedValues.cpp172
-rw-r--r--lib/Basic/Builtins.cpp23
-rw-r--r--lib/Basic/CMakeLists.txt3
-rw-r--r--lib/Basic/Cuda.cpp103
-rw-r--r--lib/Basic/Diagnostic.cpp171
-rw-r--r--lib/Basic/DiagnosticIDs.cpp6
-rw-r--r--lib/Basic/DiagnosticOptions.cpp5
-rw-r--r--lib/Basic/FileManager.cpp28
-rw-r--r--lib/Basic/FileSystemStatCache.cpp7
-rw-r--r--lib/Basic/IdentifierTable.cpp58
-rw-r--r--lib/Basic/LangOptions.cpp12
-rw-r--r--lib/Basic/Module.cpp19
-rw-r--r--lib/Basic/ObjCRuntime.cpp7
-rw-r--r--lib/Basic/OpenMPKinds.cpp14
-rw-r--r--lib/Basic/OperatorPrecedence.cpp2
-rw-r--r--lib/Basic/Sanitizers.cpp5
-rw-r--r--lib/Basic/SourceLocation.cpp30
-rw-r--r--lib/Basic/SourceManager.cpp113
-rw-r--r--lib/Basic/TargetInfo.cpp105
-rw-r--r--lib/Basic/Targets.cpp22
-rw-r--r--lib/Basic/Targets.h2
-rw-r--r--lib/Basic/Targets/AArch64.cpp64
-rw-r--r--lib/Basic/Targets/AArch64.h9
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp309
-rw-r--r--lib/Basic/Targets/AMDGPU.h234
-rw-r--r--lib/Basic/Targets/ARM.cpp34
-rw-r--r--lib/Basic/Targets/ARM.h8
-rw-r--r--lib/Basic/Targets/AVR.cpp48
-rw-r--r--lib/Basic/Targets/AVR.h3
-rw-r--r--lib/Basic/Targets/BPF.cpp12
-rw-r--r--lib/Basic/Targets/BPF.h19
-rw-r--r--lib/Basic/Targets/Hexagon.cpp35
-rw-r--r--lib/Basic/Targets/Hexagon.h2
-rw-r--r--lib/Basic/Targets/Lanai.cpp4
-rw-r--r--lib/Basic/Targets/Lanai.h2
-rw-r--r--lib/Basic/Targets/Mips.cpp43
-rw-r--r--lib/Basic/Targets/Mips.h16
-rw-r--r--lib/Basic/Targets/NVPTX.cpp37
-rw-r--r--lib/Basic/Targets/NVPTX.h10
-rw-r--r--lib/Basic/Targets/Nios2.h4
-rw-r--r--lib/Basic/Targets/OSTargets.h46
-rw-r--r--lib/Basic/Targets/PPC.cpp185
-rw-r--r--lib/Basic/Targets/PPC.h135
-rw-r--r--lib/Basic/Targets/RISCV.cpp104
-rw-r--r--lib/Basic/Targets/RISCV.h114
-rw-r--r--lib/Basic/Targets/SPIR.h5
-rw-r--r--lib/Basic/Targets/Sparc.cpp140
-rw-r--r--lib/Basic/Targets/Sparc.h49
-rw-r--r--lib/Basic/Targets/SystemZ.cpp56
-rw-r--r--lib/Basic/Targets/SystemZ.h6
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp32
-rw-r--r--lib/Basic/Targets/WebAssembly.h18
-rw-r--r--lib/Basic/Targets/X86.cpp231
-rw-r--r--lib/Basic/Targets/X86.h64
-rw-r--r--lib/Basic/VersionTuple.cpp100
-rw-r--r--lib/Basic/VirtualFileSystem.cpp363
-rw-r--r--lib/Basic/XRayInstr.cpp30
-rw-r--r--lib/Basic/XRayLists.cpp24
-rw-r--r--lib/CodeGen/ABIInfo.h15
-rw-r--r--lib/CodeGen/BackendUtil.cpp282
-rw-r--r--lib/CodeGen/CGAtomic.cpp67
-rw-r--r--lib/CodeGen/CGBlocks.cpp493
-rw-r--r--lib/CodeGen/CGBlocks.h9
-rw-r--r--lib/CodeGen/CGBuilder.h37
-rw-r--r--lib/CodeGen/CGBuiltin.cpp3055
-rw-r--r--lib/CodeGen/CGCUDANV.cpp394
-rw-r--r--lib/CodeGen/CGCXX.cpp29
-rw-r--r--lib/CodeGen/CGCXXABI.cpp14
-rw-r--r--lib/CodeGen/CGCXXABI.h29
-rw-r--r--lib/CodeGen/CGCall.cpp510
-rw-r--r--lib/CodeGen/CGCall.h114
-rw-r--r--lib/CodeGen/CGClass.cpp111
-rw-r--r--lib/CodeGen/CGCleanup.cpp48
-rw-r--r--lib/CodeGen/CGCleanup.h9
-rw-r--r--lib/CodeGen/CGCoroutine.cpp73
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp508
-rw-r--r--lib/CodeGen/CGDebugInfo.h69
-rw-r--r--lib/CodeGen/CGDecl.cpp568
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp25
-rw-r--r--lib/CodeGen/CGException.cpp299
-rw-r--r--lib/CodeGen/CGExpr.cpp201
-rw-r--r--lib/CodeGen/CGExprAgg.cpp454
-rw-r--r--lib/CodeGen/CGExprCXX.cpp80
-rw-r--r--lib/CodeGen/CGExprComplex.cpp13
-rw-r--r--lib/CodeGen/CGExprConstant.cpp174
-rw-r--r--lib/CodeGen/CGExprScalar.cpp108
-rw-r--r--lib/CodeGen/CGGPUBuiltin.cpp13
-rw-r--r--lib/CodeGen/CGLoopInfo.h70
-rw-r--r--lib/CodeGen/CGNonTrivialStruct.cpp885
-rw-r--r--lib/CodeGen/CGObjC.cpp68
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp1808
-rw-r--r--lib/CodeGen/CGObjCMac.cpp47
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp81
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.h33
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp4158
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h998
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp2300
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.h165
-rw-r--r--lib/CodeGen/CGRecordLayout.h18
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp83
-rw-r--r--lib/CodeGen/CGStmt.cpp51
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp1676
-rw-r--r--lib/CodeGen/CGVTT.cpp2
-rw-r--r--lib/CodeGen/CGVTables.cpp283
-rw-r--r--lib/CodeGen/CGVTables.h10
-rw-r--r--lib/CodeGen/CGValue.h44
-rw-r--r--lib/CodeGen/CMakeLists.txt7
-rw-r--r--lib/CodeGen/CodeGenAction.cpp54
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp255
-rw-r--r--lib/CodeGen/CodeGenFunction.h928
-rw-r--r--lib/CodeGen/CodeGenModule.cpp1020
-rw-r--r--lib/CodeGen/CodeGenModule.h155
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp8
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp31
-rw-r--r--lib/CodeGen/CodeGenTBAA.h9
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp27
-rw-r--r--lib/CodeGen/CodeGenTypes.h9
-rw-r--r--lib/CodeGen/ConstantEmitter.h2
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp153
-rw-r--r--lib/CodeGen/CoverageMappingGen.h16
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp423
-rw-r--r--lib/CodeGen/MacroPPCallbacks.cpp3
-rw-r--r--lib/CodeGen/MacroPPCallbacks.h3
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp264
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp12
-rw-r--r--lib/CodeGen/SanitizerMetadata.cpp9
-rw-r--r--lib/CodeGen/SwiftCallingConv.cpp44
-rw-r--r--lib/CodeGen/TargetInfo.cpp615
-rw-r--r--lib/CodeGen/TargetInfo.h12
-rw-r--r--lib/CodeGen/VarBypassDetector.cpp2
-rw-r--r--lib/Driver/Action.cpp47
-rw-r--r--lib/Driver/CMakeLists.txt2
-rw-r--r--lib/Driver/Compilation.cpp66
-rw-r--r--lib/Driver/Distro.cpp3
-rw-r--r--lib/Driver/Driver.cpp992
-rw-r--r--lib/Driver/Job.cpp59
-rw-r--r--lib/Driver/Multilib.cpp31
-rw-r--r--lib/Driver/SanitizerArgs.cpp192
-rw-r--r--lib/Driver/ToolChain.cpp124
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp1
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp38
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp6
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp24
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp78
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h3
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp10
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h7
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.cpp378
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.h32
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.cpp23
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp43
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp33
-rw-r--r--lib/Driver/ToolChains/BareMetal.h1
-rw-r--r--lib/Driver/ToolChains/Clang.cpp555
-rw-r--r--lib/Driver/ToolChains/Clang.h6
-rw-r--r--lib/Driver/ToolChains/CloudABI.cpp13
-rw-r--r--lib/Driver/ToolChains/CloudABI.h4
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp344
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h24
-rw-r--r--lib/Driver/ToolChains/Contiki.h4
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp3
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp228
-rw-r--r--lib/Driver/ToolChains/Cuda.h28
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp197
-rw-r--r--lib/Driver/ToolChains/Darwin.h15
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp69
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp50
-rw-r--r--lib/Driver/ToolChains/Fuchsia.h5
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp655
-rw-r--r--lib/Driver/ToolChains/Gnu.h55
-rw-r--r--lib/Driver/ToolChains/HIP.cpp350
-rw-r--r--lib/Driver/ToolChains/HIP.h123
-rw-r--r--lib/Driver/ToolChains/Haiku.cpp6
-rw-r--r--lib/Driver/ToolChains/Haiku.h4
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp59
-rw-r--r--lib/Driver/ToolChains/Hexagon.h1
-rw-r--r--lib/Driver/ToolChains/Lanai.h4
-rw-r--r--lib/Driver/ToolChains/Linux.cpp120
-rw-r--r--lib/Driver/ToolChains/Linux.h4
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp37
-rw-r--r--lib/Driver/ToolChains/MSVC.h4
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp88
-rw-r--r--lib/Driver/ToolChains/MinGW.h1
-rw-r--r--lib/Driver/ToolChains/MipsLinux.cpp9
-rw-r--r--lib/Driver/ToolChains/MipsLinux.h4
-rw-r--r--lib/Driver/ToolChains/Myriad.cpp7
-rw-r--r--lib/Driver/ToolChains/Myriad.h4
-rw-r--r--lib/Driver/ToolChains/NaCl.cpp20
-rw-r--r--lib/Driver/ToolChains/NaCl.h4
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp62
-rw-r--r--lib/Driver/ToolChains/NetBSD.h4
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp49
-rw-r--r--lib/Driver/ToolChains/OpenBSD.h4
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp11
-rw-r--r--lib/Driver/ToolChains/PS4CPU.h6
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp173
-rw-r--r--lib/Driver/ToolChains/Solaris.h11
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp22
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h2
-rw-r--r--lib/Driver/Types.cpp19
-rw-r--r--lib/Driver/XRayArgs.cpp99
-rw-r--r--lib/Edit/Commit.cpp25
-rw-r--r--lib/Edit/EditedSource.cpp27
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp8
-rw-r--r--lib/Format/AffectedRangeManager.cpp22
-rw-r--r--lib/Format/AffectedRangeManager.h11
-rw-r--r--lib/Format/BreakableToken.cpp76
-rw-r--r--lib/Format/BreakableToken.h56
-rw-r--r--lib/Format/CMakeLists.txt1
-rw-r--r--lib/Format/ContinuationIndenter.cpp458
-rw-r--r--lib/Format/ContinuationIndenter.h158
-rw-r--r--lib/Format/Encoding.h14
-rw-r--r--lib/Format/Format.cpp745
-rw-r--r--lib/Format/FormatInternal.h4
-rw-r--r--lib/Format/FormatToken.cpp3
-rw-r--r--lib/Format/FormatToken.h175
-rw-r--r--lib/Format/FormatTokenLexer.cpp10
-rw-r--r--lib/Format/FormatTokenLexer.h2
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp29
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.h12
-rw-r--r--lib/Format/SortJavaScriptImports.cpp20
-rw-r--r--lib/Format/SortJavaScriptImports.h2
-rw-r--r--lib/Format/TokenAnalyzer.cpp57
-rw-r--r--lib/Format/TokenAnalyzer.h51
-rw-r--r--lib/Format/TokenAnnotator.cpp617
-rw-r--r--lib/Format/TokenAnnotator.h12
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp119
-rw-r--r--lib/Format/UnwrappedLineFormatter.h13
-rw-r--r--lib/Format/UnwrappedLineParser.cpp302
-rw-r--r--lib/Format/UnwrappedLineParser.h44
-rw-r--r--lib/Format/UsingDeclarationsSorter.cpp7
-rw-r--r--lib/Format/UsingDeclarationsSorter.h2
-rw-r--r--lib/Format/WhitespaceManager.cpp4
-rw-r--r--lib/Format/WhitespaceManager.h36
-rw-r--r--lib/Frontend/ASTConsumers.cpp19
-rw-r--r--lib/Frontend/ASTMerge.cpp2
-rw-r--r--lib/Frontend/ASTUnit.cpp524
-rw-r--r--lib/Frontend/CMakeLists.txt1
-rw-r--r--lib/Frontend/CacheTokens.cpp32
-rw-r--r--lib/Frontend/CodeGenOptions.cpp2
-rw-r--r--lib/Frontend/CompilerInstance.cpp181
-rw-r--r--lib/Frontend/CompilerInvocation.cpp576
-rw-r--r--lib/Frontend/DependencyFile.cpp45
-rw-r--r--lib/Frontend/DependencyGraph.cpp23
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp168
-rw-r--r--lib/Frontend/FrontendAction.cpp41
-rw-r--r--lib/Frontend/FrontendActions.cpp254
-rw-r--r--lib/Frontend/FrontendOptions.cpp3
-rw-r--r--lib/Frontend/FrontendTiming.cpp20
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp16
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp94
-rw-r--r--lib/Frontend/InitPreprocessor.cpp235
-rw-r--r--lib/Frontend/LayoutOverrideSource.cpp2
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp6
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp24
-rw-r--r--lib/Frontend/PCHContainerOperations.cpp2
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp60
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp25
-rw-r--r--lib/Frontend/Rewrite/FixItRewriter.cpp31
-rw-r--r--lib/Frontend/Rewrite/HTMLPrint.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp38
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp31
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp30
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp76
-rw-r--r--lib/Frontend/SerializedDiagnosticReader.cpp31
-rw-r--r--lib/Frontend/TextDiagnostic.cpp70
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp21
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp2
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp133
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp11
-rw-r--r--lib/Headers/CMakeLists.txt26
-rw-r--r--lib/Headers/__clang_cuda_builtin_vars.h2
-rw-r--r--lib/Headers/__clang_cuda_device_functions.h1768
-rw-r--r--lib/Headers/__clang_cuda_intrinsics.h3
-rw-r--r--lib/Headers/__clang_cuda_libdevice_declares.h466
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h95
-rw-r--r--lib/Headers/__wmmintrin_aes.h25
-rw-r--r--lib/Headers/__wmmintrin_pclmul.h19
-rw-r--r--lib/Headers/ammintrin.h14
-rw-r--r--lib/Headers/avx2intrin.h658
-rw-r--r--lib/Headers/avx512bitalgintrin.h6
-rw-r--r--lib/Headers/avx512bwintrin.h866
-rw-r--r--lib/Headers/avx512cdintrin.h34
-rw-r--r--lib/Headers/avx512dqintrin.h660
-rw-r--r--lib/Headers/avx512erintrin.h128
-rw-r--r--lib/Headers/avx512fintrin.h6513
-rw-r--r--lib/Headers/avx512ifmaintrin.h48
-rw-r--r--lib/Headers/avx512ifmavlintrin.h116
-rw-r--r--lib/Headers/avx512pfintrin.h70
-rw-r--r--lib/Headers/avx512vbmi2intrin.h130
-rw-r--r--lib/Headers/avx512vbmiintrin.h66
-rw-r--r--lib/Headers/avx512vbmivlintrin.h183
-rw-r--r--lib/Headers/avx512vlbitalgintrin.h72
-rw-r--r--lib/Headers/avx512vlbwintrin.h977
-rw-r--r--lib/Headers/avx512vlcdintrin.h138
-rw-r--r--lib/Headers/avx512vldqintrin.h579
-rw-r--r--lib/Headers/avx512vlintrin.h5697
-rw-r--r--lib/Headers/avx512vlvbmi2intrin.h475
-rw-r--r--lib/Headers/avx512vlvnniintrin.h253
-rw-r--r--lib/Headers/avx512vnniintrin.h99
-rw-r--r--lib/Headers/avx512vpopcntdqintrin.h6
-rw-r--r--lib/Headers/avx512vpopcntdqvlintrin.h40
-rw-r--r--lib/Headers/avxintrin.h1181
-rw-r--r--lib/Headers/bmiintrin.h38
-rw-r--r--lib/Headers/cetintrin.h22
-rw-r--r--lib/Headers/cldemoteintrin.h42
-rw-r--r--lib/Headers/clflushoptintrin.h2
-rw-r--r--lib/Headers/clwbintrin.h2
-rw-r--r--lib/Headers/clzerointrin.h10
-rw-r--r--lib/Headers/cpuid.h14
-rw-r--r--lib/Headers/cuda_wrappers/algorithm64
-rw-r--r--lib/Headers/emmintrin.h869
-rw-r--r--lib/Headers/f16cintrin.h82
-rw-r--r--lib/Headers/fma4intrin.h70
-rw-r--r--lib/Headers/fmaintrin.h72
-rw-r--r--lib/Headers/fxsrintrin.h16
-rw-r--r--lib/Headers/gfniintrin.h112
-rw-r--r--lib/Headers/htmxlintrin.h2
-rw-r--r--lib/Headers/ia32intrin.h5
-rw-r--r--lib/Headers/immintrin.h197
-rw-r--r--lib/Headers/intrin.h158
-rw-r--r--lib/Headers/invpcidintrin.h37
-rw-r--r--lib/Headers/lwpintrin.h14
-rw-r--r--lib/Headers/lzcntintrin.h14
-rw-r--r--lib/Headers/mm3dnow.h6
-rw-r--r--lib/Headers/mmintrin.h160
-rw-r--r--lib/Headers/module.modulemap20
-rw-r--r--lib/Headers/movdirintrin.h63
-rw-r--r--lib/Headers/mwaitxintrin.h6
-rw-r--r--lib/Headers/nmmintrin.h6
-rw-r--r--lib/Headers/opencl-c.h6
-rw-r--r--lib/Headers/pconfigintrin.h50
-rw-r--r--lib/Headers/pkuintrin.h4
-rw-r--r--lib/Headers/pmmintrin.h32
-rw-r--r--lib/Headers/popcntintrin.h14
-rw-r--r--lib/Headers/prfchwintrin.h6
-rw-r--r--lib/Headers/ptwriteintrin.h51
-rw-r--r--lib/Headers/rdseedintrin.h2
-rw-r--r--lib/Headers/sgxintrin.h70
-rw-r--r--lib/Headers/shaintrin.h6
-rw-r--r--lib/Headers/smmintrin.h345
-rw-r--r--lib/Headers/stdint.h4
-rw-r--r--lib/Headers/tmmintrin.h124
-rw-r--r--lib/Headers/vaesintrin.h4
-rw-r--r--lib/Headers/vpclmulqdqintrin.h10
-rw-r--r--lib/Headers/waitpkgintrin.h56
-rw-r--r--lib/Headers/wbnoinvdintrin.h38
-rw-r--r--lib/Headers/wmmintrin.h6
-rw-r--r--lib/Headers/x86intrin.h25
-rw-r--r--lib/Headers/xmmintrin.h462
-rw-r--r--lib/Headers/xopintrin.h74
-rw-r--r--lib/Headers/xsavecintrin.h2
-rw-r--r--lib/Headers/xsaveintrin.h10
-rw-r--r--lib/Headers/xsaveoptintrin.h6
-rw-r--r--lib/Headers/xsavesintrin.h2
-rw-r--r--lib/Headers/xtestintrin.h2
-rw-r--r--lib/Index/CMakeLists.txt1
-rw-r--r--lib/Index/IndexDecl.cpp11
-rw-r--r--lib/Index/IndexSymbol.cpp12
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp2
-rw-r--r--lib/Index/IndexingAction.cpp159
-rw-r--r--lib/Index/IndexingContext.cpp57
-rw-r--r--lib/Index/IndexingContext.h15
-rw-r--r--lib/Index/SimpleFormatContext.h4
-rw-r--r--lib/Index/USRGeneration.cpp30
-rw-r--r--lib/Lex/HeaderSearch.cpp140
-rw-r--r--lib/Lex/Lexer.cpp103
-rw-r--r--lib/Lex/LiteralSupport.cpp197
-rw-r--r--lib/Lex/MacroArgs.cpp5
-rw-r--r--lib/Lex/MacroInfo.cpp2
-rw-r--r--lib/Lex/ModuleMap.cpp310
-rw-r--r--lib/Lex/PPCaching.cpp4
-rw-r--r--lib/Lex/PPDirectives.cpp124
-rw-r--r--lib/Lex/PPExpressions.cpp2
-rw-r--r--lib/Lex/PPLexerChange.cpp32
-rw-r--r--lib/Lex/PPMacroExpansion.cpp238
-rw-r--r--lib/Lex/PTHLexer.cpp10
-rw-r--r--lib/Lex/Pragma.cpp83
-rw-r--r--lib/Lex/PreprocessingRecord.cpp34
-rw-r--r--lib/Lex/Preprocessor.cpp117
-rw-r--r--lib/Lex/PreprocessorLexer.cpp2
-rw-r--r--lib/Lex/ScratchBuffer.cpp8
-rw-r--r--lib/Lex/TokenLexer.cpp14
-rw-r--r--lib/Parse/ParseAST.cpp18
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp24
-rw-r--r--lib/Parse/ParseDecl.cpp738
-rw-r--r--lib/Parse/ParseDeclCXX.cpp283
-rw-r--r--lib/Parse/ParseExpr.cpp208
-rw-r--r--lib/Parse/ParseExprCXX.cpp348
-rw-r--r--lib/Parse/ParseObjc.cpp197
-rw-r--r--lib/Parse/ParseOpenMP.cpp319
-rw-r--r--lib/Parse/ParsePragma.cpp208
-rw-r--r--lib/Parse/ParseStmt.cpp74
-rw-r--r--lib/Parse/ParseStmtAsm.cpp2
-rw-r--r--lib/Parse/ParseTemplate.cpp383
-rw-r--r--lib/Parse/ParseTentative.cpp63
-rw-r--r--lib/Parse/Parser.cpp81
-rw-r--r--lib/Rewrite/DeltaTree.cpp48
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp224
-rw-r--r--lib/Rewrite/RewriteRope.cpp77
-rw-r--r--lib/Rewrite/Rewriter.cpp42
-rw-r--r--lib/Rewrite/TokenRewriter.cpp15
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp270
-rw-r--r--lib/Sema/CMakeLists.txt2
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp162
-rw-r--r--lib/Sema/CoroutineStmtBuilder.h10
-rw-r--r--lib/Sema/DeclSpec.cpp70
-rw-r--r--lib/Sema/DelayedDiagnostic.cpp21
-rw-r--r--lib/Sema/IdentifierResolver.cpp39
-rw-r--r--lib/Sema/JumpDiagnostics.cpp12
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp18
-rw-r--r--lib/Sema/ParsedAttr.cpp (renamed from lib/Sema/AttributeList.cpp)162
-rw-r--r--lib/Sema/Scope.cpp99
-rw-r--r--lib/Sema/ScopeInfo.cpp1
-rw-r--r--lib/Sema/Sema.cpp232
-rw-r--r--lib/Sema/SemaAccess.cpp29
-rw-r--r--lib/Sema/SemaAttr.cpp17
-rw-r--r--lib/Sema/SemaCUDA.cpp88
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp21
-rw-r--r--lib/Sema/SemaCast.cpp457
-rw-r--r--lib/Sema/SemaChecking.cpp2529
-rw-r--r--lib/Sema/SemaCodeComplete.cpp2365
-rw-r--r--lib/Sema/SemaCoroutine.cpp326
-rw-r--r--lib/Sema/SemaDecl.cpp1443
-rw-r--r--lib/Sema/SemaDeclAttr.cpp4288
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1150
-rw-r--r--lib/Sema/SemaDeclObjC.cpp211
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp421
-rw-r--r--lib/Sema/SemaExpr.cpp1159
-rw-r--r--lib/Sema/SemaExprCXX.cpp588
-rw-r--r--lib/Sema/SemaExprMember.cpp152
-rw-r--r--lib/Sema/SemaExprObjC.cpp76
-rw-r--r--lib/Sema/SemaInit.cpp1076
-rw-r--r--lib/Sema/SemaLambda.cpp162
-rw-r--r--lib/Sema/SemaLookup.cpp240
-rw-r--r--lib/Sema/SemaObjCProperty.cpp24
-rw-r--r--lib/Sema/SemaOpenMP.cpp3152
-rw-r--r--lib/Sema/SemaOverload.cpp724
-rw-r--r--lib/Sema/SemaPseudoObject.cpp95
-rw-r--r--lib/Sema/SemaStmt.cpp579
-rw-r--r--lib/Sema/SemaStmtAsm.cpp4
-rw-r--r--lib/Sema/SemaStmtAttr.cpp27
-rw-r--r--lib/Sema/SemaTemplate.cpp772
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp909
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp329
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp201
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp119
-rw-r--r--lib/Sema/SemaType.cpp1488
-rw-r--r--lib/Sema/TreeTransform.h703
-rw-r--r--lib/Sema/TypeLocBuilder.h6
-rw-r--r--lib/Serialization/ASTCommon.cpp97
-rw-r--r--lib/Serialization/ASTCommon.h8
-rw-r--r--lib/Serialization/ASTReader.cpp992
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp660
-rw-r--r--lib/Serialization/ASTReaderInternals.h16
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp180
-rw-r--r--lib/Serialization/ASTWriter.cpp348
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp49
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp16
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp76
-rw-r--r--lib/Serialization/Module.cpp9
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h22
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h2
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationState.h34
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp62
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt7
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp470
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp79
-rw-r--r--lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp152
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp61
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp18
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp229
-rw-r--r--lib/StaticAnalyzer/Checkers/GTestChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp60
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp252
-rw-r--r--lib/StaticAnalyzer/Checkers/IteratorChecker.cpp512
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h2
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp328
-rw-r--r--lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp88
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp140
-rw-r--r--lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp44
-rw-r--r--lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp209
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/PaddingChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp23
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp77
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp217
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp36
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp90
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp33
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp34
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp688
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp3
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/ValistChecker.cpp28
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp113
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp62
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp2538
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp1245
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt5
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp240
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/CheckerHelpers.cpp29
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp310
-rw-r--r--lib/StaticAnalyzer/Core/CheckerRegistry.cpp72
-rw-r--r--lib/StaticAnalyzer/Core/ConstraintManager.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp257
-rw-r--r--lib/StaticAnalyzer/Core/DynamicTypeMap.cpp38
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp95
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp47
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp1088
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp49
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp530
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp224
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp94
-rw-r--r--lib/StaticAnalyzer/Core/FunctionSummary.cpp13
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp266
-rw-r--r--lib/StaticAnalyzer/Core/LoopUnrolling.cpp20
-rw-r--r--lib/StaticAnalyzer/Core/LoopWidening.cpp33
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp303
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp409
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp142
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp65
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp455
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.cpp25
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.h102
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp140
-rw-r--r--lib/StaticAnalyzer/Core/SMTConstraintManager.cpp181
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp85
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp65
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp260
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp96
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp46
-rw-r--r--lib/StaticAnalyzer/Core/WorkList.cpp254
-rw-r--r--lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp2053
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp174
-rw-r--r--lib/StaticAnalyzer/Frontend/CMakeLists.txt3
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp13
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelConsumer.cpp2
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.cpp6
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.h4
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp4
-rw-r--r--lib/Tooling/AllTUsExecution.cpp161
-rw-r--r--lib/Tooling/ArgumentsAdjusters.cpp7
-rw-r--r--lib/Tooling/CMakeLists.txt3
-rw-r--r--lib/Tooling/CompilationDatabase.cpp57
-rw-r--r--lib/Tooling/Core/CMakeLists.txt2
-rw-r--r--lib/Tooling/Core/Replacement.cpp69
-rw-r--r--lib/Tooling/Execution.cpp9
-rw-r--r--lib/Tooling/FileMatchTrie.cpp45
-rw-r--r--lib/Tooling/Inclusions/CMakeLists.txt12
-rw-r--r--lib/Tooling/Inclusions/HeaderIncludes.cpp330
-rw-r--r--lib/Tooling/Inclusions/IncludeStyle.cpp31
-rw-r--r--lib/Tooling/InterpolatingCompilationDatabase.cpp458
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp88
-rw-r--r--lib/Tooling/Refactoring/AtomicChange.cpp6
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp2
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp2
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFinder.cpp4
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFindingAction.cpp4
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp8
-rw-r--r--lib/Tooling/StandaloneExecution.cpp8
-rw-r--r--lib/Tooling/Tooling.cpp196
681 files changed, 82957 insertions, 47716 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index cf7cddefc03d..74c9974cc810 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -503,7 +503,7 @@ public:
} // end anonymous namespace.
-/// \brief Anchor for VTable.
+/// Anchor for VTable.
MigrationProcess::RewriteListener::~RewriteListener() { }
MigrationProcess::MigrationProcess(
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index fcc67da1f774..433e6194a2c2 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -226,7 +226,7 @@ namespace {
isa<ParenListExpr>(Expr) || isa<SizeOfPackExpr>(Expr));
}
- /// \brief - Rewrite message expression for Objective-C setter and getters into
+ /// - Rewrite message expression for Objective-C setter and getters into
/// property-dot syntax.
bool rewriteToPropertyDotSyntax(const ObjCMessageExpr *Msg,
Preprocessor &PP,
@@ -1065,7 +1065,7 @@ static bool TypeIsInnerPointer(QualType T) {
return true;
}
-/// \brief Check whether the two versions match.
+/// Check whether the two versions match.
static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y) {
return (X == Y);
}
@@ -1101,7 +1101,7 @@ static bool MatchTwoAttributeLists(const AttrVec &Attrs1, const AttrVec &Attrs2,
for (unsigned i = 0, e = Attrs1.size(); i != e; i++) {
bool match = false;
for (unsigned j = 0, f = Attrs2.size(); j != f; j++) {
- // Matching attribute kind only. Except for Availabilty attributes,
+ // Matching attribute kind only. Except for Availability attributes,
// we are not getting into details of the attributes. For all practical purposes
// this is sufficient.
if (Attrs1[i]->getKind() == Attrs2[j]->getKind()) {
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 9a51690c0ce7..2ad1c8591a9e 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -107,8 +107,7 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
o << " <key>ranges</key>\n";
o << " <array>\n";
for (auto &R : D.getRanges()) {
- CharSourceRange ExpansionRange(SM.getExpansionRange(R.getAsRange()),
- R.isTokenRange());
+ CharSourceRange ExpansionRange = SM.getExpansionRange(R);
EmitRange(o, SM, Lexer::getAsCharRange(ExpansionRange, SM, LangOpts),
FM, 4);
}
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index d45d5d60b78a..cbc22ed60172 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -73,7 +73,7 @@ static bool isEmptyARCMTMacroStatement(NullStmt *S,
namespace {
-/// \brief Returns true if the statement became empty due to previous
+/// Returns true if the statement became empty due to previous
/// transformations.
class EmptyChecker : public StmtVisitor<EmptyChecker, bool> {
ASTContext &Ctx;
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index 2ae6b78a4634..4fd21aa6c269 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -23,7 +23,7 @@ using namespace trans;
namespace {
-/// \brief Collects all the places where GC attributes __strong/__weak occur.
+/// Collects all the places where GC attributes __strong/__weak occur.
class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
MigrationContext &MigrateCtx;
bool FullyMigratable;
@@ -92,7 +92,7 @@ public:
ASTContext &Ctx = MigrateCtx.Pass.Ctx;
SourceManager &SM = Ctx.getSourceManager();
if (Loc.isMacroID())
- Loc = SM.getImmediateExpansionRange(Loc).first;
+ Loc = SM.getImmediateExpansionRange(Loc).getBegin();
SmallString<32> Buf;
bool Invalid = false;
StringRef Spell = Lexer::getSpelling(
@@ -287,7 +287,8 @@ static void checkAllAtProps(MigrationContext &MigrateCtx,
SourceLocation Loc = ATLs[i].first.getAttrNameLoc();
if (Loc.isMacroID())
Loc = MigrateCtx.Pass.Ctx.getSourceManager()
- .getImmediateExpansionRange(Loc).first;
+ .getImmediateExpansionRange(Loc)
+ .getBegin();
TA.remove(Loc);
TA.clearDiagnostic(diag::err_objc_property_attr_mutually_exclusive, AtLoc);
TA.clearDiagnostic(diag::err_arc_inconsistent_property_ownership,
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index 389b03666bf7..1468c21a0093 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -330,7 +330,7 @@ private:
return false;
}
- // \brief Returns true if all declarations in the @property have GC __weak.
+ // Returns true if all declarations in the @property have GC __weak.
bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const {
if (!Pass.isGCMigration())
return false;
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index 389f3655aa52..ebe289b34df8 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -158,7 +158,7 @@ public:
}
private:
- /// \brief Checks for idioms where an unused -autorelease is common.
+ /// Checks for idioms where an unused -autorelease is common.
///
/// Returns true for this idiom which is common in property
/// setters:
@@ -309,7 +309,7 @@ private:
return nullptr;
}
- /// \brief Check if the retain/release is due to a GCD/XPC macro that are
+ /// Check if the retain/release is due to a GCD/XPC macro that are
/// defined as:
///
/// #define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; })
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 7ca49558a7f0..de52bef4d206 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -283,13 +283,12 @@ private:
SourceManager &SM = Pass.Ctx.getSourceManager();
SourceLocation Loc = E->getExprLoc();
assert(Loc.isMacroID());
- SourceLocation MacroBegin, MacroEnd;
- std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
+ CharSourceRange MacroRange = SM.getImmediateExpansionRange(Loc);
SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange();
SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
- Outer = SourceRange(MacroBegin, MacroEnd);
+ Outer = MacroRange.getAsRange();
Inner = SourceRange(InnerBegin, InnerEnd);
}
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index 4f3fb5845925..704be4374d3d 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -19,7 +19,7 @@ using namespace arcmt;
namespace {
-/// \brief Collects transformations and merges them before applying them with
+/// Collects transformations and merges them before applying them with
/// with applyRewrites(). E.g. if the same source range
/// is requested to be removed twice, only one rewriter remove will be invoked.
/// Rewrites happen in "transactions"; if one rewrite in the transaction cannot
@@ -61,7 +61,7 @@ class TransformActionsImpl {
Range_ExtendsEnd
};
- /// \brief A range to remove. It is a character range.
+ /// A range to remove. It is a character range.
struct CharRange {
FullSourceLoc Begin, End;
@@ -107,7 +107,7 @@ class TransformActionsImpl {
typedef std::map<FullSourceLoc, TextsVec, FullSourceLoc::BeforeThanCompare>
InsertsMap;
InsertsMap Inserts;
- /// \brief A list of ranges to remove. They are always sorted and they never
+ /// A list of ranges to remove. They are always sorted and they never
/// intersect with each other.
std::list<CharRange> Removals;
@@ -115,7 +115,7 @@ class TransformActionsImpl {
std::vector<std::pair<CharRange, SourceLocation> > IndentationRanges;
- /// \brief Keeps text passed to transformation methods.
+ /// Keeps text passed to transformation methods.
llvm::StringMap<bool> UniqueText;
public:
@@ -167,12 +167,12 @@ private:
void addRemoval(CharSourceRange range);
void addInsertion(SourceLocation loc, StringRef text);
- /// \brief Stores text passed to the transformation methods to keep the string
+ /// Stores text passed to the transformation methods to keep the string
/// "alive". Since the vast majority of text will be the same, we also unique
/// the strings using a StringMap.
StringRef getUniqueText(StringRef text);
- /// \brief Computes the source location just past the end of the token at
+ /// Computes the source location just past the end of the token at
/// the given source location. If the location points at a macro, the whole
/// macro expansion is skipped.
static SourceLocation getLocForEndOfToken(SourceLocation loc,
@@ -577,21 +577,25 @@ void TransformActionsImpl::applyRewrites(
}
}
-/// \brief Stores text passed to the transformation methods to keep the string
+/// Stores text passed to the transformation methods to keep the string
/// "alive". Since the vast majority of text will be the same, we also unique
/// the strings using a StringMap.
StringRef TransformActionsImpl::getUniqueText(StringRef text) {
return UniqueText.insert(std::make_pair(text, false)).first->first();
}
-/// \brief Computes the source location just past the end of the token at
+/// Computes the source location just past the end of the token at
/// the given source location. If the location points at a macro, the whole
/// macro expansion is skipped.
SourceLocation TransformActionsImpl::getLocForEndOfToken(SourceLocation loc,
SourceManager &SM,
Preprocessor &PP) {
- if (loc.isMacroID())
- loc = SM.getExpansionRange(loc).second;
+ if (loc.isMacroID()) {
+ CharSourceRange Exp = SM.getExpansionRange(loc);
+ if (Exp.isCharRange())
+ return Exp.getEnd();
+ loc = Exp.getEnd();
+ }
return PP.getLocForEndOfToken(loc);
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index cb96a547fbac..1f4e6a297fc3 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -111,7 +111,7 @@ bool trans::isPlusOne(const Expr *E) {
return implCE && implCE->getCastKind() == CK_ARCConsumeObject;
}
-/// \brief 'Loc' is the end of a statement range. This returns the location
+/// 'Loc' is the end of a statement range. This returns the location
/// immediately after the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned
/// source location will be invalid.
@@ -123,7 +123,7 @@ SourceLocation trans::findLocationAfterSemi(SourceLocation loc,
return SemiLoc.getLocWithOffset(1);
}
-/// \brief \arg Loc is the end of a statement range. This returns the location
+/// \arg Loc is the end of a statement range. This returns the location
/// of the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned
/// source location will be invalid.
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
index 7e3dd34e7607..8ea4f79456a8 100644
--- a/lib/ARCMigrate/Transforms.h
+++ b/lib/ARCMigrate/Transforms.h
@@ -89,7 +89,7 @@ public:
SourceLocation Loc;
QualType ModifiedType;
Decl *Dcl;
- /// \brief true if the attribute is owned, e.g. it is in a body and not just
+ /// true if the attribute is owned, e.g. it is in a body and not just
/// in an interface.
bool FullyMigratable;
};
@@ -97,7 +97,7 @@ public:
llvm::DenseSet<unsigned> AttrSet;
llvm::DenseSet<unsigned> RemovedAttrSet;
- /// \brief Set of raw '@' locations for 'assign' properties group that contain
+ /// Set of raw '@' locations for 'assign' properties group that contain
/// GC __weak.
llvm::DenseSet<unsigned> AtPropsWeak;
@@ -156,21 +156,21 @@ public:
// Helpers.
//===----------------------------------------------------------------------===//
-/// \brief Determine whether we can add weak to the given type.
+/// Determine whether we can add weak to the given type.
bool canApplyWeak(ASTContext &Ctx, QualType type,
bool AllowOnUnknownClass = false);
bool isPlusOneAssign(const BinaryOperator *E);
bool isPlusOne(const Expr *E);
-/// \brief 'Loc' is the end of a statement range. This returns the location
+/// 'Loc' is the end of a statement range. This returns the location
/// immediately after the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned
/// source location will be invalid.
SourceLocation findLocationAfterSemi(SourceLocation loc, ASTContext &Ctx,
bool IsDecl = false);
-/// \brief 'Loc' is the end of a statement range. This returns the location
+/// 'Loc' is the end of a statement range. This returns the location
/// of the semicolon following the statement.
/// If no semicolon is found or the location is inside a macro, the returned
/// source location will be invalid.
@@ -179,7 +179,7 @@ SourceLocation findSemiAfterLocation(SourceLocation loc, ASTContext &Ctx,
bool hasSideEffects(Expr *E, ASTContext &Ctx);
bool isGlobalVar(Expr *E);
-/// \brief Returns "nil" or "0" if 'nil' macro is not actually defined.
+/// Returns "nil" or "0" if 'nil' macro is not actually defined.
StringRef getNilString(MigrationPass &Pass);
template <typename BODY_TRANS>
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 488ad3373ca3..c45b52a65a4d 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -23,14 +23,57 @@ using namespace clang;
namespace {
struct LVBase {
- llvm::PointerIntPair<APValue::LValueBase, 1, bool> BaseAndIsOnePastTheEnd;
+ APValue::LValueBase Base;
CharUnits Offset;
unsigned PathLength;
- unsigned CallIndex;
- bool IsNullPtr;
+ bool IsNullPtr : 1;
+ bool IsOnePastTheEnd : 1;
};
}
+void *APValue::LValueBase::getOpaqueValue() const {
+ return Ptr.getOpaqueValue();
+}
+
+bool APValue::LValueBase::isNull() const {
+ return Ptr.isNull();
+}
+
+APValue::LValueBase::operator bool () const {
+ return static_cast<bool>(Ptr);
+}
+
+clang::APValue::LValueBase
+llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
+ return clang::APValue::LValueBase(
+ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(),
+ DenseMapInfo<unsigned>::getEmptyKey(),
+ DenseMapInfo<unsigned>::getEmptyKey());
+}
+
+clang::APValue::LValueBase
+llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
+ return clang::APValue::LValueBase(
+ DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(),
+ DenseMapInfo<unsigned>::getTombstoneKey(),
+ DenseMapInfo<unsigned>::getTombstoneKey());
+}
+
+unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
+ const clang::APValue::LValueBase &Base) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Base.getOpaqueValue());
+ ID.AddInteger(Base.getCallIndex());
+ ID.AddInteger(Base.getVersion());
+ return ID.ComputeHash();
+}
+
+bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
+ const clang::APValue::LValueBase &LHS,
+ const clang::APValue::LValueBase &RHS) {
+ return LHS == RHS;
+}
+
struct APValue::LV : LVBase {
static const unsigned InlinePathSpace =
(DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
@@ -150,11 +193,10 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
MakeLValue();
if (RHS.hasLValuePath())
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), RHS.getLValuePath(),
- RHS.isLValueOnePastTheEnd(), RHS.getLValueCallIndex(),
- RHS.isNullPointer());
+ RHS.isLValueOnePastTheEnd(), RHS.isNullPointer());
else
setLValue(RHS.getLValueBase(), RHS.getLValueOffset(), NoLValuePath(),
- RHS.getLValueCallIndex(), RHS.isNullPointer());
+ RHS.isNullPointer());
break;
case Array:
MakeArray(RHS.getArrayInitializedElts(), RHS.getArraySize());
@@ -552,12 +594,12 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
+ return ((const LV*)(const void*)Data.buffer)->Base;
}
bool APValue::isLValueOnePastTheEnd() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
+ return ((const LV*)(const void*)Data.buffer)->IsOnePastTheEnd;
}
CharUnits &APValue::getLValueOffset() {
@@ -578,7 +620,12 @@ ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
unsigned APValue::getLValueCallIndex() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data.buffer)->CallIndex;
+ return ((const LV*)(const char*)Data.buffer)->Base.getCallIndex();
+}
+
+unsigned APValue::getLValueVersion() const {
+ assert(isLValue() && "Invalid accessor");
+ return ((const LV*)(const char*)Data.buffer)->Base.getVersion();
}
bool APValue::isNullPointer() const {
@@ -587,26 +634,24 @@ bool APValue::isNullPointer() const {
}
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
- unsigned CallIndex, bool IsNullPtr) {
+ bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
LV &LVal = *((LV*)(char*)Data.buffer);
- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
- LVal.BaseAndIsOnePastTheEnd.setInt(false);
+ LVal.Base = B;
+ LVal.IsOnePastTheEnd = false;
LVal.Offset = O;
- LVal.CallIndex = CallIndex;
LVal.resizePath((unsigned)-1);
LVal.IsNullPtr = IsNullPtr;
}
void APValue::setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
- unsigned CallIndex, bool IsNullPtr) {
+ bool IsNullPtr) {
assert(isLValue() && "Invalid accessor");
LV &LVal = *((LV*)(char*)Data.buffer);
- LVal.BaseAndIsOnePastTheEnd.setPointer(B);
- LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
+ LVal.Base = B;
+ LVal.IsOnePastTheEnd = IsOnePastTheEnd;
LVal.Offset = O;
- LVal.CallIndex = CallIndex;
LVal.resizePath(Path.size());
memcpy(LVal.getPath(), Path.data(), Path.size() * sizeof(LValuePathEntry));
LVal.IsNullPtr = IsNullPtr;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3dc961d4f12b..25dc4441aafd 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -47,6 +47,7 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CommentOptions.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -130,35 +131,34 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
return nullptr;
// User can not attach documentation to implicit instantiations.
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->isStaticDataMember() &&
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {
if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
TSK == TSK_Undeclared)
return nullptr;
}
- if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+ if (const auto *ED = dyn_cast<EnumDecl>(D)) {
if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return nullptr;
}
- if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ if (const auto *TD = dyn_cast<TagDecl>(D)) {
// When tag declaration (but not definition!) is part of the
// decl-specifier-seq of some other declaration, it doesn't get comment
if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
@@ -201,7 +201,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// declared via a macro. Try using declaration's starting location as
// the "declaration location".
DeclLoc = D->getLocStart();
- } else if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ } else if (const auto *TD = dyn_cast<TagDecl>(D)) {
// If location of the tag decl is inside a macro, but the spelling of
// the tag name comes from a macro argument, it looks like a special
// macro like NS_ENUM is being used to define the tag decl. In that
@@ -226,8 +226,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// for is usually among the last two comments we parsed -- check them
// first.
RawComment CommentAtDeclLoc(
- SourceMgr, SourceRange(DeclLoc), false,
- LangOpts.CommentOpts.ParseAllComments);
+ SourceMgr, SourceRange(DeclLoc), LangOpts.CommentOpts, false);
BeforeThanCompare<RawComment> Compare(SourceMgr);
ArrayRef<RawComment *>::iterator MaybeBeforeDecl = RawComments.end() - 1;
bool Found = Compare(*MaybeBeforeDecl, &CommentAtDeclLoc);
@@ -253,7 +252,8 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// First check whether we have a trailing comment.
if (Comment != RawComments.end() &&
- (*Comment)->isDocumentation() && (*Comment)->isTrailingComment() &&
+ ((*Comment)->isDocumentation() || LangOpts.CommentOpts.ParseAllComments)
+ && (*Comment)->isTrailingComment() &&
(isa<FieldDecl>(D) || isa<EnumConstantDecl>(D) || isa<VarDecl>(D) ||
isa<ObjCMethodDecl>(D) || isa<ObjCPropertyDecl>(D))) {
std::pair<FileID, unsigned> CommentBeginDecomp
@@ -275,7 +275,9 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
--Comment;
// Check that we actually have a non-member Doxygen comment.
- if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
+ if (!((*Comment)->isDocumentation() ||
+ LangOpts.CommentOpts.ParseAllComments) ||
+ (*Comment)->isTrailingComment())
return nullptr;
// Decompose the end of the comment.
@@ -310,7 +312,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
/// refer to the actual template.
/// If we have an implicit instantiation, adjust 'D' to refer to template.
static const Decl *adjustDeclToTemplate(const Decl *D) {
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// Is this function declaration part of a function template?
if (const FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate())
return FTD;
@@ -330,7 +332,7 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
// Static data member is instantiated from a member definition of a class
// template?
if (VD->isStaticDataMember())
@@ -339,15 +341,14 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
+ if (const auto *CRD = dyn_cast<CXXRecordDecl>(D)) {
// Is this class declaration part of a class template?
if (const ClassTemplateDecl *CTD = CRD->getDescribedClassTemplate())
return CTD;
// Class is an implicit instantiation of a class template or partial
// specialization?
- if (const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CRD)) {
if (CTSD->getSpecializationKind() != TSK_ImplicitInstantiation)
return D;
llvm::PointerUnion<ClassTemplateDecl *,
@@ -366,7 +367,7 @@ static const Decl *adjustDeclToTemplate(const Decl *D) {
return D;
}
- if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
+ if (const auto *ED = dyn_cast<EnumDecl>(D)) {
// Enum is instantiated from a member definition of a class template?
if (const EnumDecl *MemberDecl = ED->getInstantiatedFromMemberEnum())
return MemberDecl;
@@ -428,7 +429,7 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
}
// If we found a comment, it should be a documentation comment.
- assert(!RC || RC->isDocumentation());
+ assert(!RC || RC->isDocumentation() || LangOpts.CommentOpts.ParseAllComments);
if (OriginalDecl)
*OriginalDecl = OriginalDeclForRC;
@@ -451,7 +452,7 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
SmallVectorImpl<const NamedDecl *> &Redeclared) {
const DeclContext *DC = ObjCMethod->getDeclContext();
- if (const ObjCImplDecl *IMD = dyn_cast<ObjCImplDecl>(DC)) {
+ if (const auto *IMD = dyn_cast<ObjCImplDecl>(DC)) {
const ObjCInterfaceDecl *ID = IMD->getClassInterface();
if (!ID)
return;
@@ -467,7 +468,7 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
const Decl *D) const {
- comments::DeclInfo *ThisDeclInfo = new (*this) comments::DeclInfo;
+ auto *ThisDeclInfo = new (*this) comments::DeclInfo;
ThisDeclInfo->CommentDecl = D;
ThisDeclInfo->IsFilled = false;
ThisDeclInfo->fill();
@@ -511,7 +512,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
if (!RC) {
if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
SmallVector<const NamedDecl*, 8> Overridden;
- const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D);
+ const auto *OMD = dyn_cast<ObjCMethodDecl>(D);
if (OMD && OMD->isPropertyAccessor())
if (const ObjCPropertyDecl *PDecl = OMD->findPropertyDecl())
if (comments::FullComment *FC = getCommentForDecl(PDecl, PP))
@@ -523,28 +524,28 @@ comments::FullComment *ASTContext::getCommentForDecl(
if (comments::FullComment *FC = getCommentForDecl(Overridden[i], PP))
return cloneFullComment(FC, D);
}
- else if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+ else if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
// Attach any tag type's documentation to its typedef if latter
// does not have one of its own.
QualType QT = TD->getUnderlyingType();
- if (const TagType *TT = QT->getAs<TagType>())
+ if (const auto *TT = QT->getAs<TagType>())
if (const Decl *TD = TT->getDecl())
if (comments::FullComment *FC = getCommentForDecl(TD, PP))
return cloneFullComment(FC, D);
}
- else if (const ObjCInterfaceDecl *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
+ else if (const auto *IC = dyn_cast<ObjCInterfaceDecl>(D)) {
while (IC->getSuperClass()) {
IC = IC->getSuperClass();
if (comments::FullComment *FC = getCommentForDecl(IC, PP))
return cloneFullComment(FC, D);
}
}
- else if (const ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+ else if (const auto *CD = dyn_cast<ObjCCategoryDecl>(D)) {
if (const ObjCInterfaceDecl *IC = CD->getClassInterface())
if (comments::FullComment *FC = getCommentForDecl(IC, PP))
return cloneFullComment(FC, D);
}
- else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
if (!(RD = RD->getDefinition()))
return nullptr;
// Check non-virtual bases.
@@ -604,13 +605,13 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
ID.AddInteger(0);
ID.AddBoolean(TTP->isParameterPack());
continue;
}
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+ if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
ID.AddInteger(1);
ID.AddBoolean(NTTP->isParameterPack());
ID.AddPointer(NTTP->getType().getCanonicalType().getAsOpaquePtr());
@@ -626,7 +627,7 @@ ASTContext::CanonicalTemplateTemplateParm::Profile(llvm::FoldingSetNodeID &ID,
continue;
}
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+ auto *TTP = cast<TemplateTemplateParmDecl>(*P);
ID.AddInteger(2);
Profile(ID, TTP);
}
@@ -651,7 +652,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
for (TemplateParameterList::const_iterator P = Params->begin(),
PEnd = Params->end();
P != PEnd; ++P) {
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P))
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(*P))
CanonParams.push_back(
TemplateTypeParmDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
@@ -659,8 +660,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
TTP->getDepth(),
TTP->getIndex(), nullptr, false,
TTP->isParameterPack()));
- else if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+ else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
QualType T = getCanonicalType(NTTP->getType());
TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
NonTypeTemplateParmDecl *Param;
@@ -788,10 +788,12 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
SubstTemplateTemplateParmPacks(this_()), SourceMgr(SM), LangOpts(LOpts),
SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
- LangOpts.XRayNeverInstrumentFiles, SM)),
+ LangOpts.XRayNeverInstrumentFiles,
+ LangOpts.XRayAttrListFiles, SM)),
PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
BuiltinInfo(builtins), DeclarationNames(*this), Comments(SM),
- CommentCommandTraits(BumpAlloc, LOpts.CommentOpts), LastSDM(nullptr, 0) {
+ CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
+ CompCategories(this_()), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
}
@@ -812,13 +814,13 @@ ASTContext::~ASTContext() {
const ASTRecordLayout*>::iterator
I = ObjCLayouts.begin(), E = ObjCLayouts.end(); I != E; )
// Increment in loop to prevent using deallocated memory.
- if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
R->Destroy(*this);
for (llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*>::iterator
I = ASTRecordLayouts.begin(), E = ASTRecordLayouts.end(); I != E; ) {
// Increment in loop to prevent using deallocated memory.
- if (ASTRecordLayout *R = const_cast<ASTRecordLayout*>((I++)->second))
+ if (auto *R = const_cast<ASTRecordLayout *>((I++)->second))
R->Destroy(*this);
}
@@ -966,7 +968,7 @@ void ASTContext::PerModuleInitializers::resolve(ASTContext &Ctx) {
void ASTContext::addModuleInitializer(Module *M, Decl *D) {
// One special case: if we add a module initializer that imports another
// module, and that module's only initializer is an ImportDecl, simplify.
- if (auto *ID = dyn_cast<ImportDecl>(D)) {
+ if (const auto *ID = dyn_cast<ImportDecl>(D)) {
auto It = ModuleInitializers.find(ID->getImportedModule());
// Maybe the ImportDecl does nothing at all. (Common case.)
@@ -997,7 +999,7 @@ void ASTContext::addLazyModuleInitializers(Module *M, ArrayRef<uint32_t> IDs) {
IDs.begin(), IDs.end());
}
-ArrayRef<Decl*> ASTContext::getModuleInitializers(Module *M) {
+ArrayRef<Decl *> ASTContext::getModuleInitializers(Module *M) {
auto It = ModuleInitializers.find(M);
if (It == ModuleInitializers.end())
return None;
@@ -1079,7 +1081,7 @@ TypedefDecl *ASTContext::getUInt128Decl() const {
}
void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
- BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
+ auto *Ty = new (*this, TypeAlignment) BuiltinType(K);
R = CanQualType::CreateUnsafe(QualType(Ty, 0));
Types.push_back(Ty);
}
@@ -1132,6 +1134,32 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// C11 extension ISO/IEC TS 18661-3
InitBuiltinType(Float16Ty, BuiltinType::Float16);
+ // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+ InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum);
+ InitBuiltinType(AccumTy, BuiltinType::Accum);
+ InitBuiltinType(LongAccumTy, BuiltinType::LongAccum);
+ InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
+ InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum);
+ InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum);
+ InitBuiltinType(ShortFractTy, BuiltinType::ShortFract);
+ InitBuiltinType(FractTy, BuiltinType::Fract);
+ InitBuiltinType(LongFractTy, BuiltinType::LongFract);
+ InitBuiltinType(UnsignedShortFractTy, BuiltinType::UShortFract);
+ InitBuiltinType(UnsignedFractTy, BuiltinType::UFract);
+ InitBuiltinType(UnsignedLongFractTy, BuiltinType::ULongFract);
+ InitBuiltinType(SatShortAccumTy, BuiltinType::SatShortAccum);
+ InitBuiltinType(SatAccumTy, BuiltinType::SatAccum);
+ InitBuiltinType(SatLongAccumTy, BuiltinType::SatLongAccum);
+ InitBuiltinType(SatUnsignedShortAccumTy, BuiltinType::SatUShortAccum);
+ InitBuiltinType(SatUnsignedAccumTy, BuiltinType::SatUAccum);
+ InitBuiltinType(SatUnsignedLongAccumTy, BuiltinType::SatULongAccum);
+ InitBuiltinType(SatShortFractTy, BuiltinType::SatShortFract);
+ InitBuiltinType(SatFractTy, BuiltinType::SatFract);
+ InitBuiltinType(SatLongFractTy, BuiltinType::SatLongFract);
+ InitBuiltinType(SatUnsignedShortFractTy, BuiltinType::SatUShortFract);
+ InitBuiltinType(SatUnsignedFractTy, BuiltinType::SatUFract);
+ InitBuiltinType(SatUnsignedLongFractTy, BuiltinType::SatULongFract);
+
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
@@ -1150,6 +1178,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
WIntTy = getFromTargetType(Target.getWIntType());
+ // C++20 (proposed)
+ InitBuiltinType(Char8Ty, BuiltinType::Char8);
+
if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
InitBuiltinType(Char16Ty, BuiltinType::Char16);
else // C99
@@ -1254,7 +1285,7 @@ AttrVec& ASTContext::getDeclAttrs(const Decl *D) {
return *Result;
}
-/// \brief Erase the attributes corresponding to the given declaration.
+/// Erase the attributes corresponding to the given declaration.
void ASTContext::eraseDeclAttrs(const Decl *D) {
llvm::DenseMap<const Decl*, AttrVec*>::iterator Pos = DeclAttrs.find(D);
if (Pos != DeclAttrs.end()) {
@@ -1276,7 +1307,7 @@ ASTContext::getTemplateOrSpecializationInfo(const VarDecl *Var) {
llvm::DenseMap<const VarDecl *, TemplateOrSpecializationInfo>::iterator Pos =
TemplateOrInstantiation.find(Var);
if (Pos == TemplateOrInstantiation.end())
- return TemplateOrSpecializationInfo();
+ return {};
return Pos->second;
}
@@ -1412,13 +1443,13 @@ void ASTContext::getOverriddenMethods(
SmallVectorImpl<const NamedDecl *> &Overridden) const {
assert(D);
- if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
+ if (const auto *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
Overridden.append(overridden_methods_begin(CXXMethod),
overridden_methods_end(CXXMethod));
return;
}
- const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
+ const auto *Method = dyn_cast<ObjCMethodDecl>(D);
if (!Method)
return;
@@ -1447,7 +1478,7 @@ void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
/// getFloatTypeSemantics - Return the APFloat 'semantics' for the specified
/// scalar floating point type.
const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
- const BuiltinType *BT = T->getAs<BuiltinType>();
+ const auto *BT = T->getAs<BuiltinType>();
assert(BT && "Not a floating point type!");
switch (BT->getKind()) {
default: llvm_unreachable("Not a floating point type!");
@@ -1490,9 +1521,9 @@ 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)) {
+ } else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
+ if (const auto *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
@@ -1517,7 +1548,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (BaseT.getQualifiers().hasUnaligned())
Align = Target->getCharWidth();
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (VD->hasGlobalStorage() && !ForAlignof)
Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
}
@@ -1528,7 +1559,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
// a max-field-alignment constraint (#pragma pack). So calculate
// the actual alignment of the field within the struct, and then
// (as we're expected to) constrain that by the alignment of the type.
- if (const FieldDecl *Field = dyn_cast<FieldDecl>(VD)) {
+ if (const auto *Field = dyn_cast<FieldDecl>(VD)) {
const RecordDecl *Parent = Field->getParent();
// We can only produce a sensible answer if the record is valid.
if (!Parent->isInvalidDecl()) {
@@ -1567,7 +1598,7 @@ ASTContext::getTypeInfoDataSizeInChars(QualType T) const {
// of a base-class subobject. We decide whether that's possible
// during class layout, so here we can just trust the layout results.
if (getLangOpts().CPlusPlus) {
- if (const RecordType *RT = T->getAs<RecordType>()) {
+ if (const auto *RT = T->getAs<RecordType>()) {
const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());
sizeAndAlign.first = layout.getDataSize();
}
@@ -1598,7 +1629,7 @@ static getConstantArrayInfoInChars(const ASTContext &Context,
std::pair<CharUnits, CharUnits>
ASTContext::getTypeInfoInChars(const Type *T) const {
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(T))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
return getConstantArrayInfoInChars(*this, CAT);
TypeInfo Info = getTypeInfo(T);
return std::make_pair(toCharUnitsFromBits(Info.Width),
@@ -1620,7 +1651,7 @@ bool ASTContext::isAlignmentRequired(QualType T) const {
unsigned ASTContext::getTypeAlignIfKnown(QualType T) const {
// An alignment on a typedef overrides anything else.
- if (auto *TT = T->getAs<TypedefType>())
+ if (const auto *TT = T->getAs<TypedefType>())
if (unsigned Align = TT->getDecl()->getMaxAlignment())
return Align;
@@ -1631,12 +1662,12 @@ unsigned ASTContext::getTypeAlignIfKnown(QualType T) const {
// If we had an array type, its element type might be a typedef
// type with an alignment attribute.
- if (auto *TT = T->getAs<TypedefType>())
+ if (const auto *TT = T->getAs<TypedefType>())
if (unsigned Align = TT->getDecl()->getMaxAlignment())
return Align;
// Otherwise, see if the declaration of the type had an attribute.
- if (auto *TT = T->getAs<TagType>())
+ if (const auto *TT = T->getAs<TagType>())
return TT->getDecl()->getMaxAlignment();
return 0;
@@ -1690,7 +1721,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
case Type::ConstantArray: {
- const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
+ const auto *CAT = cast<ConstantArrayType>(T);
TypeInfo EltInfo = getTypeInfo(CAT->getElementType());
uint64_t Size = CAT->getSize().getZExtValue();
@@ -1705,7 +1736,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::ExtVector:
case Type::Vector: {
- const VectorType *VT = cast<VectorType>(T);
+ const auto *VT = cast<VectorType>(T);
TypeInfo EltInfo = getTypeInfo(VT->getElementType());
Width = EltInfo.Width * VT->getNumElements();
Align = Width;
@@ -1738,6 +1769,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case BuiltinType::Char_U:
case BuiltinType::UChar:
case BuiltinType::SChar:
+ case BuiltinType::Char8:
Width = Target->getCharWidth();
Align = Target->getCharAlign();
break;
@@ -1779,6 +1811,48 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 128;
Align = 128; // int128_t is 128-bit aligned on all targets.
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatUShortAccum:
+ Width = Target->getShortAccumWidth();
+ Align = Target->getShortAccumAlign();
+ break;
+ case BuiltinType::Accum:
+ case BuiltinType::UAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatUAccum:
+ Width = Target->getAccumWidth();
+ Align = Target->getAccumAlign();
+ break;
+ case BuiltinType::LongAccum:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatULongAccum:
+ Width = Target->getLongAccumWidth();
+ Align = Target->getLongAccumAlign();
+ break;
+ case BuiltinType::ShortFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatUShortFract:
+ Width = Target->getShortFractWidth();
+ Align = Target->getShortFractAlign();
+ break;
+ case BuiltinType::Fract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatUFract:
+ Width = Target->getFractWidth();
+ Align = Target->getFractAlign();
+ break;
+ case BuiltinType::LongFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatULongFract:
+ Width = Target->getLongFractWidth();
+ Align = Target->getLongFractAlign();
+ break;
case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
@@ -1848,7 +1922,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = Target->getPointerAlign(AS);
break;
case Type::MemberPointer: {
- const MemberPointerType *MPT = cast<MemberPointerType>(T);
+ const auto *MPT = cast<MemberPointerType>(T);
CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);
Width = MPI.Width;
Align = MPI.Align;
@@ -1868,7 +1942,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Decayed:
return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
case Type::ObjCInterface: {
- const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
+ const auto *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
Width = toBits(Layout.getSize());
Align = toBits(Layout.getAlignment());
@@ -1876,7 +1950,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::Record:
case Type::Enum: {
- const TagType *TT = cast<TagType>(T);
+ const auto *TT = cast<TagType>(T);
if (TT->getDecl()->isInvalidDecl()) {
Width = 8;
@@ -1884,7 +1958,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
}
- if (const EnumType *ET = dyn_cast<EnumType>(TT)) {
+ if (const auto *ET = dyn_cast<EnumType>(TT)) {
const EnumDecl *ED = ET->getDecl();
TypeInfo Info =
getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType());
@@ -1895,7 +1969,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return Info;
}
- const RecordType *RT = cast<RecordType>(TT);
+ const auto *RT = cast<RecordType>(TT);
const RecordDecl *RD = RT->getDecl();
const ASTRecordLayout &Layout = getASTRecordLayout(RD);
Width = toBits(Layout.getSize());
@@ -1910,7 +1984,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Auto:
case Type::DeducedTemplateSpecialization: {
- const DeducedType *A = cast<DeducedType>(T);
+ const auto *A = cast<DeducedType>(T);
assert(!A->getDeducedType().isNull() &&
"cannot request the size of an undeduced or dependent auto type");
return getTypeInfo(A->getDeducedType().getTypePtr());
@@ -1952,10 +2026,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = Info.Width;
Align = Info.Align;
- // If the size of the type doesn't exceed the platform's max
- // atomic promotion width, make the size and alignment more
- // favorable to atomic operations:
- if (Width != 0 && Width <= Target->getMaxAtomicPromoteWidth()) {
+ if (!Width) {
+ // An otherwise zero-sized type should still generate an
+ // atomic operation.
+ Width = Target->getCharWidth();
+ assert(Align);
+ } else if (Width <= Target->getMaxAtomicPromoteWidth()) {
+ // If the size of the type doesn't exceed the platform's max
+ // atomic promotion width, make the size and alignment more
+ // favorable to atomic operations:
+
// Round the size up to a power of 2.
if (!llvm::isPowerOf2_64(Width))
Width = llvm::NextPowerOf2(Width);
@@ -2033,9 +2113,9 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
return ABIAlign;
// Double and long long should be naturally aligned if possible.
- if (const ComplexType *CT = T->getAs<ComplexType>())
+ if (const auto *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
T = ET->getDecl()->getIntegerType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
T->isSpecificBuiltinType(BuiltinType::LongLong) ||
@@ -2091,7 +2171,7 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
for (const auto *I : OI->ivars())
Ivars.push_back(I);
} else {
- ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
+ auto *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
Iv= Iv->getNextIvar())
Ivars.push_back(Iv);
@@ -2102,7 +2182,7 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
/// those inherited by it.
void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols) {
- if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
+ if (const auto *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
// We can use protocol_iterator here instead of
// all_referenced_protocol_iterator since we are walking all categories.
for (auto *Proto : OI->all_referenced_protocols()) {
@@ -2118,11 +2198,11 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
CollectInheritedProtocols(SD, Protocols);
SD = SD->getSuperClass();
}
- } else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
+ } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
for (auto *Proto : OC->protocols()) {
CollectInheritedProtocols(Proto, Protocols);
}
- } else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
+ } else if (const auto *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
// Insert the protocol.
if (!Protocols.insert(
const_cast<ObjCProtocolDecl *>(OP->getCanonicalDecl())).second)
@@ -2145,7 +2225,7 @@ static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
if (FieldSize != UnionSize)
return false;
}
- return true;
+ return !RD->field_empty();
}
static bool isStructEmpty(QualType Ty) {
@@ -2184,7 +2264,7 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
}
}
- std::sort(
+ llvm::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()) <
@@ -2264,7 +2344,7 @@ bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
return true;
if (Ty->isMemberPointerType()) {
- const MemberPointerType *MPT = Ty->getAs<MemberPointerType>();
+ const auto *MPT = Ty->getAs<MemberPointerType>();
return !ABI->getMemberPointerInfo(MPT).HasPadding;
}
@@ -2330,7 +2410,7 @@ bool ASTContext::isSentinelNullExpr(const Expr *E) {
return false;
}
-/// \brief Get the implementation of ObjCInterfaceDecl, or nullptr if none
+/// Get the implementation of ObjCInterfaceDecl, or nullptr if none
/// exists.
ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
@@ -2340,7 +2420,7 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)
return nullptr;
}
-/// \brief Get the implementation of ObjCCategoryDecl, or nullptr if none
+/// Get the implementation of ObjCCategoryDecl, or nullptr if none
/// exists.
ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
llvm::DenseMap<ObjCContainerDecl*, ObjCImplDecl*>::iterator
@@ -2350,14 +2430,14 @@ ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
return nullptr;
}
-/// \brief Set the implementation of ObjCInterfaceDecl.
+/// Set the implementation of ObjCInterfaceDecl.
void ASTContext::setObjCImplementation(ObjCInterfaceDecl *IFaceD,
ObjCImplementationDecl *ImplD) {
assert(IFaceD && ImplD && "Passed null params");
ObjCImpls[IFaceD] = ImplD;
}
-/// \brief Set the implementation of ObjCCategoryDecl.
+/// Set the implementation of ObjCCategoryDecl.
void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD,
ObjCCategoryImplDecl *ImplD) {
assert(CatD && ImplD && "Passed null params");
@@ -2377,20 +2457,17 @@ void ASTContext::setObjCMethodRedeclaration(const ObjCMethodDecl *MD,
const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
const NamedDecl *ND) const {
- if (const ObjCInterfaceDecl *ID =
- dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))
+ if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND->getDeclContext()))
return ID;
- if (const ObjCCategoryDecl *CD =
- dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))
+ if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND->getDeclContext()))
return CD->getClassInterface();
- if (const ObjCImplDecl *IMD =
- dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
+ if (const auto *IMD = dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
return IMD->getClassInterface();
return nullptr;
}
-/// \brief Get the copy initialization expression of VarDecl, or nullptr if
+/// Get the copy initialization expression of VarDecl, or nullptr if
/// none exists.
Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
assert(VD && "Passed null params");
@@ -2398,10 +2475,10 @@ Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
"getBlockVarCopyInits - not __block var");
llvm::DenseMap<const VarDecl*, Expr*>::iterator
I = BlockVarCopyInits.find(VD);
- return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr;
+ return (I != BlockVarCopyInits.end()) ? I->second : nullptr;
}
-/// \brief Set the copy inialization expression of a block var decl.
+/// Set the copy inialization expression of a block var decl.
void ASTContext::setBlockVarCopyInits(VarDecl*VD, Expr* Init) {
assert(VD && Init && "Passed null params");
assert(VD->hasAttr<BlocksAttr>() &&
@@ -2417,7 +2494,7 @@ TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
assert(DataSize == TypeLoc::getFullDataSizeForType(T) &&
"incorrect data size provided to CreateTypeSourceInfo!");
- TypeSourceInfo *TInfo =
+ auto *TInfo =
(TypeSourceInfo*)BumpAlloc.Allocate(sizeof(TypeSourceInfo) + DataSize, 8);
new (TInfo) TypeSourceInfo(T);
return TInfo;
@@ -2470,7 +2547,7 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
(void) ExtQualNodes.FindNodeOrInsertPos(ID, insertPos);
}
- ExtQuals *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals);
+ auto *eq = new (*this, TypeAlignment) ExtQuals(baseType, canon, quals);
ExtQualNodes.InsertNode(eq, insertPos);
return QualType(eq, fastQuals);
}
@@ -2522,7 +2599,7 @@ QualType ASTContext::getObjCGCQualType(QualType T,
if (CanT.getObjCGCAttr() == GCAttr)
return T;
- if (const PointerType *ptr = T->getAs<PointerType>()) {
+ if (const auto *ptr = T->getAs<PointerType>()) {
QualType Pointee = ptr->getPointeeType();
if (Pointee->isAnyPointerType()) {
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
@@ -2550,10 +2627,10 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,
return T;
QualType Result;
- if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
+ if (const auto *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
} else {
- const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
+ const auto *FPT = cast<FunctionProtoType>(T);
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = Info;
Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
@@ -2566,7 +2643,7 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
QualType ResultType) {
FD = FD->getMostRecentDecl();
while (true) {
- const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
+ const auto *FPT = FD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
if (FunctionDecl *Next = FD->getPreviousDecl())
@@ -2582,26 +2659,24 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
/// specified exception specification. Type sugar that can be present on a
/// declaration of a function with an exception specification is permitted
/// and preserved. Other type sugar (for instance, typedefs) is not.
-static QualType getFunctionTypeWithExceptionSpec(
- ASTContext &Context, QualType Orig,
- const FunctionProtoType::ExceptionSpecInfo &ESI) {
+QualType ASTContext::getFunctionTypeWithExceptionSpec(
+ QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) {
// Might have some parens.
- if (auto *PT = dyn_cast<ParenType>(Orig))
- return Context.getParenType(
- getFunctionTypeWithExceptionSpec(Context, PT->getInnerType(), ESI));
+ if (const auto *PT = dyn_cast<ParenType>(Orig))
+ return getParenType(
+ getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
// Might have a calling-convention attribute.
- if (auto *AT = dyn_cast<AttributedType>(Orig))
- return Context.getAttributedType(
+ if (const auto *AT = dyn_cast<AttributedType>(Orig))
+ return getAttributedType(
AT->getAttrKind(),
- getFunctionTypeWithExceptionSpec(Context, AT->getModifiedType(), ESI),
- getFunctionTypeWithExceptionSpec(Context, AT->getEquivalentType(),
- ESI));
+ getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
+ getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
// Anything else must be a function type. Rebuild it with the new exception
// specification.
- const FunctionProtoType *Proto = cast<FunctionProtoType>(Orig);
- return Context.getFunctionType(
+ const auto *Proto = cast<FunctionProtoType>(Orig);
+ return getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(),
Proto->getExtProtoInfo().withExceptionSpec(ESI));
}
@@ -2610,8 +2685,8 @@ bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
QualType U) {
return hasSameType(T, U) ||
(getLangOpts().CPlusPlus17 &&
- hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
- getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
+ hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),
+ getFunctionTypeWithExceptionSpec(U, EST_None)));
}
void ASTContext::adjustExceptionSpec(
@@ -2619,7 +2694,7 @@ void ASTContext::adjustExceptionSpec(
bool AsWritten) {
// Update the type.
QualType Updated =
- getFunctionTypeWithExceptionSpec(*this, FD->getType(), ESI);
+ getFunctionTypeWithExceptionSpec(FD->getType(), ESI);
FD->setType(Updated);
if (!AsWritten)
@@ -2630,7 +2705,7 @@ void ASTContext::adjustExceptionSpec(
// If the type and the type-as-written differ, we may need to update
// the type-as-written too.
if (TSInfo->getType() != FD->getType())
- Updated = getFunctionTypeWithExceptionSpec(*this, TSInfo->getType(), ESI);
+ Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);
// FIXME: When we get proper type location information for exceptions,
// we'll also have to rebuild the TypeSourceInfo. For now, we just patch
@@ -2664,7 +2739,7 @@ QualType ASTContext::getComplexType(QualType T) const {
ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
Types.push_back(New);
ComplexTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2692,7 +2767,7 @@ QualType ASTContext::getPointerType(QualType T) const {
PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) PointerType(T, Canonical);
Types.push_back(New);
PointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2783,8 +2858,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- BlockPointerType *New
- = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) BlockPointerType(T, Canonical);
Types.push_back(New);
BlockPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2807,7 +2881,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
- const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+ const auto *InnerRef = T->getAs<ReferenceType>();
// If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field.
@@ -2822,9 +2896,8 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- LValueReferenceType *New
- = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
- SpelledAsLValue);
+ auto *New = new (*this, TypeAlignment) LValueReferenceType(T, Canonical,
+ SpelledAsLValue);
Types.push_back(New);
LValueReferenceTypes.InsertNode(New, InsertPos);
@@ -2844,7 +2917,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
- const ReferenceType *InnerRef = T->getAs<ReferenceType>();
+ const auto *InnerRef = T->getAs<ReferenceType>();
// If the referencee type isn't canonical, this won't be a canonical type
// either, so fill in the canonical type field.
@@ -2859,8 +2932,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- RValueReferenceType *New
- = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) RValueReferenceType(T, Canonical);
Types.push_back(New);
RValueReferenceTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2890,8 +2962,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- MemberPointerType *New
- = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
+ auto *New = new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
Types.push_back(New);
MemberPointerTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -2935,7 +3006,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ConstantArrayType *New = new(*this,TypeAlignment)
+ auto *New = new (*this,TypeAlignment)
ConstantArrayType(EltTy, Canon, ArySize, ASM, IndexTypeQuals);
ConstantArrayTypes.InsertNode(New, InsertPos);
Types.push_back(New);
@@ -2964,6 +3035,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::Builtin:
case Type::Complex:
case Type::Vector:
+ case Type::DependentVector:
case Type::ExtVector:
case Type::DependentSizedExtVector:
case Type::DependentAddressSpace:
@@ -3007,7 +3079,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
break;
case Type::LValueReference: {
- const LValueReferenceType *lv = cast<LValueReferenceType>(ty);
+ const auto *lv = cast<LValueReferenceType>(ty);
result = getLValueReferenceType(
getVariableArrayDecayedType(lv->getPointeeType()),
lv->isSpelledAsLValue());
@@ -3015,20 +3087,20 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
}
case Type::RValueReference: {
- const RValueReferenceType *lv = cast<RValueReferenceType>(ty);
+ const auto *lv = cast<RValueReferenceType>(ty);
result = getRValueReferenceType(
getVariableArrayDecayedType(lv->getPointeeType()));
break;
}
case Type::Atomic: {
- const AtomicType *at = cast<AtomicType>(ty);
+ const auto *at = cast<AtomicType>(ty);
result = getAtomicType(getVariableArrayDecayedType(at->getValueType()));
break;
}
case Type::ConstantArray: {
- const ConstantArrayType *cat = cast<ConstantArrayType>(ty);
+ const auto *cat = cast<ConstantArrayType>(ty);
result = getConstantArrayType(
getVariableArrayDecayedType(cat->getElementType()),
cat->getSize(),
@@ -3038,7 +3110,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
}
case Type::DependentSizedArray: {
- const DependentSizedArrayType *dat = cast<DependentSizedArrayType>(ty);
+ const auto *dat = cast<DependentSizedArrayType>(ty);
result = getDependentSizedArrayType(
getVariableArrayDecayedType(dat->getElementType()),
dat->getSizeExpr(),
@@ -3050,7 +3122,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
// Turn incomplete types into [*] types.
case Type::IncompleteArray: {
- const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty);
+ const auto *iat = cast<IncompleteArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(iat->getElementType()),
/*size*/ nullptr,
@@ -3062,7 +3134,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
// Turn VLA types into [*] types.
case Type::VariableArray: {
- const VariableArrayType *vat = cast<VariableArrayType>(ty);
+ const auto *vat = cast<VariableArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(vat->getElementType()),
/*size*/ nullptr,
@@ -3096,7 +3168,7 @@ QualType ASTContext::getVariableArrayType(QualType EltTy,
Canon = getQualifiedType(Canon, canonSplit.Quals);
}
- VariableArrayType *New = new(*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
VariableArrayType(EltTy, Canon, NumElts, ASM, IndexTypeQuals, Brackets);
VariableArrayTypes.push_back(New);
@@ -3121,7 +3193,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
// initializer. We do no canonicalization here at all, which is okay
// because they can't be used in most locations.
if (!numElements) {
- DependentSizedArrayType *newType
+ auto *newType
= new (*this, TypeAlignment)
DependentSizedArrayType(*this, elementType, QualType(),
numElements, ASM, elementTypeQuals,
@@ -3167,7 +3239,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
// Otherwise, we need to build a type which follows the spelling
// of the element type.
- DependentSizedArrayType *sugaredType
+ auto *sugaredType
= new (*this, TypeAlignment)
DependentSizedArrayType(*this, elementType, canon, numElements,
ASM, elementTypeQuals, brackets);
@@ -3203,7 +3275,7 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType,
assert(!existing && "Shouldn't be in the map!"); (void) existing;
}
- IncompleteArrayType *newType = new (*this, TypeAlignment)
+ auto *newType = new (*this, TypeAlignment)
IncompleteArrayType(elementType, canon, ASM, elementTypeQuals);
IncompleteArrayTypes.InsertNode(newType, insertPos);
@@ -3235,13 +3307,52 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- VectorType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
VectorType(vecType, NumElts, Canonical, VecKind);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
}
+QualType
+ASTContext::getDependentVectorType(QualType VecType, Expr *SizeExpr,
+ SourceLocation AttrLoc,
+ VectorType::VectorKind VecKind) const {
+ llvm::FoldingSetNodeID ID;
+ DependentVectorType::Profile(ID, *this, getCanonicalType(VecType), SizeExpr,
+ VecKind);
+ void *InsertPos = nullptr;
+ DependentVectorType *Canon =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ DependentVectorType *New;
+
+ if (Canon) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(Canon, 0), SizeExpr, AttrLoc, VecKind);
+ } else {
+ QualType CanonVecTy = getCanonicalType(VecType);
+ if (CanonVecTy == VecType) {
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, QualType(), SizeExpr, AttrLoc, VecKind);
+
+ DependentVectorType *CanonCheck =
+ DependentVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!CanonCheck &&
+ "Dependent-sized vector_size canonical type broken");
+ (void)CanonCheck;
+ DependentVectorTypes.InsertNode(New, InsertPos);
+ } else {
+ QualType Canon = getDependentSizedExtVectorType(CanonVecTy, SizeExpr,
+ SourceLocation());
+ New = new (*this, TypeAlignment) DependentVectorType(
+ *this, VecType, Canon, SizeExpr, AttrLoc, VecKind);
+ }
+ }
+
+ Types.push_back(New);
+ return QualType(New, 0);
+}
+
/// getExtVectorType - Return the unique reference to an extended vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType
@@ -3266,7 +3377,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- ExtVectorType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
ExtVectorType(vecType, NumElts, Canonical);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
@@ -3342,7 +3453,7 @@ QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
canonTy->getAddrSpaceExpr() == AddrSpaceExpr)
return QualType(canonTy, 0);
- DependentAddressSpaceType *sugaredType
+ auto *sugaredType
= new (*this, TypeAlignment)
DependentAddressSpaceType(*this, PointeeType, QualType(canonTy, 0),
AddrSpaceExpr, AttrLoc);
@@ -3350,7 +3461,7 @@ QualType ASTContext::getDependentAddressSpaceType(QualType PointeeType,
return QualType(sugaredType, 0);
}
-/// \brief Determine whether \p T is canonical as the result type of a function.
+/// Determine whether \p T is canonical as the result type of a function.
static bool isCanonicalResultType(QualType T) {
return T.isCanonical() &&
(T.getObjCLifetime() == Qualifiers::OCL_None ||
@@ -3382,7 +3493,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- FunctionNoProtoType *New = new (*this, TypeAlignment)
+ auto *New = new (*this, TypeAlignment)
FunctionNoProtoType(ResultTy, Canonical, Info);
Types.push_back(New);
FunctionNoProtoTypes.InsertNode(New, InsertPos);
@@ -3416,6 +3527,11 @@ static bool isCanonicalExceptionSpecification(
if (ESI.Type == EST_BasicNoexcept)
return true;
+ // A noexcept(expr) specification is (possibly) canonical if expr is
+ // value-dependent.
+ if (ESI.Type == EST_DependentNoexcept)
+ return true;
+
// A dynamic exception specification is canonical if it only contains pack
// expansions (so we can't tell whether it's non-throwing) and all its
// contained types are canonical.
@@ -3430,11 +3546,6 @@ static bool isCanonicalExceptionSpecification(
return AnyPackExpansions;
}
- // A noexcept(expr) specification is (possibly) canonical if expr is
- // value-dependent.
- if (ESI.Type == EST_ComputedNoexcept)
- return ESI.NoexceptExpr && ESI.NoexceptExpr->isValueDependent();
-
return false;
}
@@ -3462,7 +3573,7 @@ QualType ASTContext::getFunctionTypeInternal(
// noexcept expression, or we're just looking for a canonical type.
// Otherwise, we're going to need to create a type
// sugar node to hold the concrete expression.
- if (OnlyWantCanonical || EPI.ExceptionSpec.Type != EST_ComputedNoexcept ||
+ if (OnlyWantCanonical || !isComputedNoexcept(EPI.ExceptionSpec.Type) ||
EPI.ExceptionSpec.NoexceptExpr == FPT->getNoexceptExpr())
return Existing;
@@ -3509,7 +3620,7 @@ QualType ASTContext::getFunctionTypeInternal(
// We don't know yet. It shouldn't matter what we pick here; no-one
// should ever look at this.
LLVM_FALLTHROUGH;
- case EST_None: case EST_MSAny:
+ case EST_None: case EST_MSAny: case EST_NoexceptFalse:
CanonicalEPI.ExceptionSpec.Type = EST_None;
break;
@@ -3531,24 +3642,12 @@ QualType ASTContext::getFunctionTypeInternal(
break;
}
- case EST_DynamicNone: case EST_BasicNoexcept:
+ case EST_DynamicNone: case EST_BasicNoexcept: case EST_NoexceptTrue:
CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;
break;
- case EST_ComputedNoexcept:
- llvm::APSInt Value(1);
- auto *E = CanonicalEPI.ExceptionSpec.NoexceptExpr;
- if (!E || !E->isIntegerConstantExpr(Value, *this, nullptr,
- /*IsEvaluated*/false)) {
- // This noexcept specification is invalid.
- // FIXME: Should this be able to happen?
- CanonicalEPI.ExceptionSpec.Type = EST_None;
- break;
- }
-
- CanonicalEPI.ExceptionSpec.Type =
- Value.getBoolValue() ? EST_BasicNoexcept : EST_None;
- break;
+ case EST_DependentNoexcept:
+ llvm_unreachable("dependent noexcept is already canonical");
}
} else {
CanonicalEPI.ExceptionSpec = FunctionProtoType::ExceptionSpecInfo();
@@ -3573,18 +3672,10 @@ QualType ASTContext::getFunctionTypeInternal(
// Instead of the exception types, there could be a noexcept
// expression, or information used to resolve the exception
// specification.
- size_t Size = sizeof(FunctionProtoType) +
- NumArgs * sizeof(QualType);
-
- if (EPI.ExceptionSpec.Type == EST_Dynamic) {
- Size += EPI.ExceptionSpec.Exceptions.size() * sizeof(QualType);
- } else if (EPI.ExceptionSpec.Type == EST_ComputedNoexcept) {
- Size += sizeof(Expr*);
- } else if (EPI.ExceptionSpec.Type == EST_Uninstantiated) {
- Size += 2 * sizeof(FunctionDecl*);
- } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) {
- Size += sizeof(FunctionDecl*);
- }
+ size_t Size =
+ sizeof(FunctionProtoType) + NumArgs * sizeof(QualType) +
+ FunctionProtoType::getExceptionSpecSize(
+ EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());
// Put the ExtParameterInfos last. If all were equal, it would make
// more sense to put these before the exception specification, because
@@ -3596,7 +3687,7 @@ QualType ASTContext::getFunctionTypeInternal(
Size += NumArgs * sizeof(FunctionProtoType::ExtParameterInfo);
}
- FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);
+ auto *FTP = (FunctionProtoType *) Allocate(Size, TypeAlignment);
FunctionProtoType::ExtProtoInfo newEPI = EPI;
new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);
Types.push_back(FTP);
@@ -3624,12 +3715,18 @@ QualType ASTContext::getPipeType(QualType T, bool ReadOnly) const {
assert(!NewIP && "Shouldn't be in the map!");
(void)NewIP;
}
- PipeType *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly);
+ auto *New = new (*this, TypeAlignment) PipeType(T, Canonical, ReadOnly);
Types.push_back(New);
PipeTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
}
+QualType ASTContext::adjustStringLiteralBaseType(QualType Ty) const {
+ // OpenCL v1.1 s6.5.3: a string literal is in the constant address space.
+ return LangOpts.OpenCL ? getAddrSpaceQualType(Ty, LangAS::opencl_constant)
+ : Ty;
+}
+
QualType ASTContext::getReadPipeType(QualType T) const {
return getPipeType(T, true);
}
@@ -3641,7 +3738,7 @@ QualType ASTContext::getWritePipeType(QualType T) const {
#ifndef NDEBUG
static bool NeedsInjectedClassNameType(const RecordDecl *D) {
if (!isa<CXXRecordDecl>(D)) return false;
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
+ const auto *RD = cast<CXXRecordDecl>(D);
if (isa<ClassTemplatePartialSpecializationDecl>(RD))
return true;
if (RD->getDescribedClassTemplate() &&
@@ -3677,21 +3774,20 @@ QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
assert(Decl && "Passed null for Decl param");
assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
- if (const TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Decl))
+ if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))
return getTypedefType(Typedef);
assert(!isa<TemplateTypeParmDecl>(Decl) &&
"Template type parameter types are always available.");
- if (const RecordDecl *Record = dyn_cast<RecordDecl>(Decl)) {
+ if (const auto *Record = dyn_cast<RecordDecl>(Decl)) {
assert(Record->isFirstDecl() && "struct/union has previous declaration");
assert(!NeedsInjectedClassNameType(Record));
return getRecordType(Record);
- } else if (const EnumDecl *Enum = dyn_cast<EnumDecl>(Decl)) {
+ } else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) {
assert(Enum->isFirstDecl() && "enum has previous declaration");
return getEnumType(Enum);
- } else if (const UnresolvedUsingTypenameDecl *Using =
- dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
+ } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
Type *newType = new (*this, TypeAlignment) UnresolvedUsingType(Using);
Decl->TypeForDecl = newType;
Types.push_back(newType);
@@ -3710,7 +3806,7 @@ ASTContext::getTypedefType(const TypedefNameDecl *Decl,
if (Canonical.isNull())
Canonical = getCanonicalType(Decl->getUnderlyingType());
- TypedefType *newType = new(*this, TypeAlignment)
+ auto *newType = new (*this, TypeAlignment)
TypedefType(Type::Typedef, Decl, Canonical);
Decl->TypeForDecl = newType;
Types.push_back(newType);
@@ -3724,7 +3820,7 @@ QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
if (PrevDecl->TypeForDecl)
return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
- RecordType *newType = new (*this, TypeAlignment) RecordType(Decl);
+ auto *newType = new (*this, TypeAlignment) RecordType(Decl);
Decl->TypeForDecl = newType;
Types.push_back(newType);
return QualType(newType, 0);
@@ -3737,7 +3833,7 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
if (PrevDecl->TypeForDecl)
return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
- EnumType *newType = new (*this, TypeAlignment) EnumType(Decl);
+ auto *newType = new (*this, TypeAlignment) EnumType(Decl);
Decl->TypeForDecl = newType;
Types.push_back(newType);
return QualType(newType, 0);
@@ -3763,7 +3859,7 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
return QualType(type, 0);
}
-/// \brief Retrieve a substitution-result type.
+/// Retrieve a substitution-result type.
QualType
ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
QualType Replacement) const {
@@ -3786,7 +3882,7 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
return QualType(SubstParm, 0);
}
-/// \brief Retrieve a
+/// Retrieve a
QualType ASTContext::getSubstTemplateTypeParmPackType(
const TemplateTypeParmType *Parm,
const TemplateArgument &ArgPack) {
@@ -3812,7 +3908,7 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos);
}
- SubstTemplateTypeParmPackType *SubstParm
+ auto *SubstParm
= new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon,
ArgPack);
Types.push_back(SubstParm);
@@ -3820,7 +3916,7 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
return QualType(SubstParm, 0);
}
-/// \brief Retrieve the template type parameter type for a template
+/// Retrieve the template type parameter type for a template
/// parameter or parameter pack with the given depth, index, and (optionally)
/// name.
QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
@@ -3931,7 +4027,7 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
sizeof(TemplateArgument) * Args.size() +
(IsTypeAlias? sizeof(QualType) : 0),
TypeAlignment);
- TemplateSpecializationType *Spec
+ auto *Spec
= new (Mem) TemplateSpecializationType(Template, Args, CanonType,
IsTypeAlias ? Underlying : QualType());
@@ -3983,12 +4079,12 @@ QualType ASTContext::getCanonicalTemplateSpecializationType(
return QualType(Spec, 0);
}
-QualType
-ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType) const {
+QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier *NNS,
+ QualType NamedType,
+ TagDecl *OwnedTagDecl) const {
llvm::FoldingSetNodeID ID;
- ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
+ ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl);
void *InsertPos = nullptr;
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -4003,7 +4099,8 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
(void)CheckT;
}
- T = new (*this, TypeAlignment) ElaboratedType(Keyword, NNS, NamedType, Canon);
+ T = new (*this, TypeAlignment)
+ ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
Types.push_back(T);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
@@ -4126,7 +4223,7 @@ ASTContext::getDependentTemplateSpecializationType(
TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
TemplateArgument Arg;
- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+ if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
QualType ArgType = getTypeDeclType(TTP);
if (TTP->isParameterPack())
ArgType = getPackExpansionType(ArgType, None);
@@ -4265,7 +4362,7 @@ QualType ASTContext::getObjCObjectType(
// type.
ArrayRef<QualType> effectiveTypeArgs = typeArgs;
if (effectiveTypeArgs.empty()) {
- if (auto baseObject = baseType->getAs<ObjCObjectType>())
+ if (const auto *baseObject = baseType->getAs<ObjCObjectType>())
effectiveTypeArgs = baseObject->getTypeArgs();
}
@@ -4313,7 +4410,7 @@ QualType ASTContext::getObjCObjectType(
size += typeArgs.size() * sizeof(QualType);
size += protocols.size() * sizeof(ObjCProtocolDecl *);
void *mem = Allocate(size, TypeAlignment);
- ObjCObjectTypeImpl *T =
+ auto *T =
new (mem) ObjCObjectTypeImpl(canonical, baseType, typeArgs, protocols,
isKindOf);
@@ -4331,15 +4428,14 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
bool allowOnPointerType) const {
hasError = false;
- if (const ObjCTypeParamType *objT =
- dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
+ if (const auto *objT = dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
return getObjCTypeParamType(objT->getDecl(), protocols);
}
// Apply protocol qualifiers to ObjCObjectPointerType.
if (allowOnPointerType) {
- if (const ObjCObjectPointerType *objPtr =
- dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
+ if (const auto *objPtr =
+ dyn_cast<ObjCObjectPointerType>(type.getTypePtr())) {
const ObjCObjectType *objT = objPtr->getObjectType();
// Merge protocol lists and construct ObjCObjectType.
SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
@@ -4357,7 +4453,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
}
// Apply protocol qualifiers to ObjCObjectType.
- if (const ObjCObjectType *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
+ if (const auto *objT = dyn_cast<ObjCObjectType>(type.getTypePtr())){
// FIXME: Check for protocols to which the class type is already
// known to conform.
@@ -4379,7 +4475,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// id<protocol-list>
if (type->isObjCIdType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ const auto *objPtr = type->castAs<ObjCObjectPointerType>();
type = getObjCObjectType(ObjCBuiltinIdTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
@@ -4387,7 +4483,7 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
// Class<protocol-list>
if (type->isObjCClassType()) {
- const ObjCObjectPointerType *objPtr = type->castAs<ObjCObjectPointerType>();
+ const auto *objPtr = type->castAs<ObjCObjectPointerType>();
type = getObjCObjectType(ObjCBuiltinClassTy, {}, protocols,
objPtr->isKindOfType());
return getObjCObjectPointerType(type);
@@ -4424,8 +4520,7 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
unsigned size = sizeof(ObjCTypeParamType);
size += protocols.size() * sizeof(ObjCProtocolDecl *);
void *mem = Allocate(size, TypeAlignment);
- ObjCTypeParamType *newType = new (mem)
- ObjCTypeParamType(Decl, Canonical, protocols);
+ auto *newType = new (mem) ObjCTypeParamType(Decl, Canonical, protocols);
Types.push_back(newType);
ObjCTypeParamTypes.InsertNode(newType, InsertPos);
@@ -4440,7 +4535,7 @@ bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,
if (!QT->isObjCQualifiedIdType())
return false;
- if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) {
+ if (const auto *OPT = QT->getAs<ObjCObjectPointerType>()) {
// If both the right and left sides have qualifiers.
for (auto *Proto : OPT->quals()) {
if (!IC->ClassImplementsProtocol(Proto, false))
@@ -4458,7 +4553,7 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
ObjCInterfaceDecl *IDecl) {
if (!QT->isObjCQualifiedIdType())
return false;
- const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ const auto *OPT = QT->getAs<ObjCObjectPointerType>();
if (!OPT)
return false;
if (!IDecl->hasDefinition())
@@ -4467,7 +4562,7 @@ bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
CollectInheritedProtocols(IDecl, InheritedProtocols);
if (InheritedProtocols.empty())
return false;
- // Check that if every protocol in list of id<plist> conforms to a protcol
+ // Check that if every protocol in list of id<plist> conforms to a protocol
// of IDecl's, then bridge casting is ok.
bool Conforms = false;
for (auto *Proto : OPT->quals()) {
@@ -4520,7 +4615,7 @@ QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
// No match.
void *Mem = Allocate(sizeof(ObjCObjectPointerType), TypeAlignment);
- ObjCObjectPointerType *QType =
+ auto *QType =
new (Mem) ObjCObjectPointerType(Canonical, ObjectT);
Types.push_back(QType);
@@ -4546,7 +4641,7 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
Decl = Def;
void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
- ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
+ auto *T = new (Mem) ObjCInterfaceType(Decl);
Decl->TypeForDecl = T;
Types.push_back(T);
return QualType(T, 0);
@@ -4593,12 +4688,12 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
/// on canonical types (which are always unique).
QualType ASTContext::getTypeOfType(QualType tofType) const {
QualType Canonical = getCanonicalType(tofType);
- TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
+ auto *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
Types.push_back(tot);
return QualType(tot, 0);
}
-/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// Unlike many "get<Type>" functions, we don't unique DecltypeType
/// nodes. This would never be helpful, since each such type has its own
/// expression, and would not give a significant memory saving, since there
/// is an Expr tree under each such type.
@@ -4683,9 +4778,8 @@ QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
- AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType,
- Keyword,
- IsDependent);
+ auto *AT = new (*this, TypeAlignment)
+ AutoType(DeducedType, Keyword, IsDependent);
Types.push_back(AT);
if (InsertPos)
AutoTypes.InsertNode(AT, InsertPos);
@@ -4706,7 +4800,7 @@ QualType ASTContext::getDeducedTemplateSpecializationType(
DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(DTST, 0);
- DeducedTemplateSpecializationType *DTST = new (*this, TypeAlignment)
+ auto *DTST = new (*this, TypeAlignment)
DeducedTemplateSpecializationType(Template, DeducedType, IsDependent);
Types.push_back(DTST);
if (InsertPos)
@@ -4736,7 +4830,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
+ auto *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
Types.push_back(New);
AtomicTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
@@ -4820,14 +4914,14 @@ QualType ASTContext::getPointerDiffType() const {
return getFromTargetType(Target->getPtrDiffType(0));
}
-/// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+/// 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
+/// 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 {
return getFromTargetType(Target->getProcessIDType());
@@ -4863,8 +4957,8 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
// the unqualified desugared type and then drops it on the floor.
// We then have to strip that sugar back off with
// getUnqualifiedDesugaredType(), which is silly.
- const ArrayType *AT =
- dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
+ const auto *AT =
+ dyn_cast<ArrayType>(splitType.Ty->getUnqualifiedDesugaredType());
// If we don't have an array, just use the results in splitType.
if (!AT) {
@@ -4888,16 +4982,16 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
// build the type back up.
quals.addConsistentQualifiers(splitType.Quals);
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(AT)) {
return getConstantArrayType(unqualElementType, CAT->getSize(),
CAT->getSizeModifier(), 0);
}
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {
+ if (const auto *IAT = dyn_cast<IncompleteArrayType>(AT)) {
return getIncompleteArrayType(unqualElementType, IAT->getSizeModifier(), 0);
}
- if (const VariableArrayType *VAT = dyn_cast<VariableArrayType>(AT)) {
+ if (const auto *VAT = dyn_cast<VariableArrayType>(AT)) {
return getVariableArrayType(unqualElementType,
VAT->getSizeExpr(),
VAT->getSizeModifier(),
@@ -4905,31 +4999,66 @@ QualType ASTContext::getUnqualifiedArrayType(QualType type,
VAT->getBracketsRange());
}
- const DependentSizedArrayType *DSAT = cast<DependentSizedArrayType>(AT);
+ const auto *DSAT = cast<DependentSizedArrayType>(AT);
return getDependentSizedArrayType(unqualElementType, DSAT->getSizeExpr(),
DSAT->getSizeModifier(), 0,
SourceRange());
}
-/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that
-/// may be similar (C++ 4.4), replaces T1 and T2 with the type that
-/// they point to and return true. If T1 and T2 aren't pointer types
-/// or pointer-to-member types, or if they are not similar at this
-/// level, returns false and leaves T1 and T2 unchanged. Top-level
-/// qualifiers on T1 and T2 are ignored. This function will typically
-/// be called in a loop that successively "unwraps" pointer and
-/// pointer-to-member types to compare them at each level.
-bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) {
- const PointerType *T1PtrType = T1->getAs<PointerType>(),
- *T2PtrType = T2->getAs<PointerType>();
+/// Attempt to unwrap two types that may both be array types with the same bound
+/// (or both be array types of unknown bound) for the purpose of comparing the
+/// cv-decomposition of two types per C++ [conv.qual].
+bool ASTContext::UnwrapSimilarArrayTypes(QualType &T1, QualType &T2) {
+ bool UnwrappedAny = false;
+ while (true) {
+ auto *AT1 = getAsArrayType(T1);
+ if (!AT1) return UnwrappedAny;
+
+ auto *AT2 = getAsArrayType(T2);
+ if (!AT2) return UnwrappedAny;
+
+ // If we don't have two array types with the same constant bound nor two
+ // incomplete array types, we've unwrapped everything we can.
+ if (auto *CAT1 = dyn_cast<ConstantArrayType>(AT1)) {
+ auto *CAT2 = dyn_cast<ConstantArrayType>(AT2);
+ if (!CAT2 || CAT1->getSize() != CAT2->getSize())
+ return UnwrappedAny;
+ } else if (!isa<IncompleteArrayType>(AT1) ||
+ !isa<IncompleteArrayType>(AT2)) {
+ return UnwrappedAny;
+ }
+
+ T1 = AT1->getElementType();
+ T2 = AT2->getElementType();
+ UnwrappedAny = true;
+ }
+}
+
+/// Attempt to unwrap two types that may be similar (C++ [conv.qual]).
+///
+/// If T1 and T2 are both pointer types of the same kind, or both array types
+/// with the same bound, unwraps layers from T1 and T2 until a pointer type is
+/// unwrapped. Top-level qualifiers on T1 and T2 are ignored.
+///
+/// This function will typically be called in a loop that successively
+/// "unwraps" pointer and pointer-to-member types to compare them at each
+/// level.
+///
+/// \return \c true if a pointer type was unwrapped, \c false if we reached a
+/// pair of types that can't be unwrapped further.
+bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2) {
+ UnwrapSimilarArrayTypes(T1, T2);
+
+ const auto *T1PtrType = T1->getAs<PointerType>();
+ const auto *T2PtrType = T2->getAs<PointerType>();
if (T1PtrType && T2PtrType) {
T1 = T1PtrType->getPointeeType();
T2 = T2PtrType->getPointeeType();
return true;
}
-
- const MemberPointerType *T1MPType = T1->getAs<MemberPointerType>(),
- *T2MPType = T2->getAs<MemberPointerType>();
+
+ const auto *T1MPType = T1->getAs<MemberPointerType>();
+ const auto *T2MPType = T2->getAs<MemberPointerType>();
if (T1MPType && T2MPType &&
hasSameUnqualifiedType(QualType(T1MPType->getClass(), 0),
QualType(T2MPType->getClass(), 0))) {
@@ -4939,8 +5068,8 @@ bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) {
}
if (getLangOpts().ObjC1) {
- const ObjCObjectPointerType *T1OPType = T1->getAs<ObjCObjectPointerType>(),
- *T2OPType = T2->getAs<ObjCObjectPointerType>();
+ const auto *T1OPType = T1->getAs<ObjCObjectPointerType>();
+ const auto *T2OPType = T2->getAs<ObjCObjectPointerType>();
if (T1OPType && T2OPType) {
T1 = T1OPType->getPointeeType();
T2 = T2OPType->getPointeeType();
@@ -4953,6 +5082,37 @@ bool ASTContext::UnwrapSimilarPointerTypes(QualType &T1, QualType &T2) {
return false;
}
+bool ASTContext::hasSimilarType(QualType T1, QualType T2) {
+ while (true) {
+ Qualifiers Quals;
+ T1 = getUnqualifiedArrayType(T1, Quals);
+ T2 = getUnqualifiedArrayType(T2, Quals);
+ if (hasSameType(T1, T2))
+ return true;
+ if (!UnwrapSimilarTypes(T1, T2))
+ return false;
+ }
+}
+
+bool ASTContext::hasCvrSimilarType(QualType T1, QualType T2) {
+ while (true) {
+ Qualifiers Quals1, Quals2;
+ T1 = getUnqualifiedArrayType(T1, Quals1);
+ T2 = getUnqualifiedArrayType(T2, Quals2);
+
+ Quals1.removeCVRQualifiers();
+ Quals2.removeCVRQualifiers();
+ if (Quals1 != Quals2)
+ return false;
+
+ if (hasSameType(T1, T2))
+ return true;
+
+ if (!UnwrapSimilarTypes(T1, T2))
+ return false;
+ }
+}
+
DeclarationNameInfo
ASTContext::getNameForTemplate(TemplateName Name,
SourceLocation NameLoc) const {
@@ -5008,8 +5168,7 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
case TemplateName::QualifiedTemplate:
case TemplateName::Template: {
TemplateDecl *Template = Name.getAsTemplateDecl();
- if (TemplateTemplateParmDecl *TTP
- = dyn_cast<TemplateTemplateParmDecl>(Template))
+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template))
Template = getCanonicalTemplateTemplateParmDecl(TTP);
// The canonical template name is the canonical template declaration.
@@ -5061,7 +5220,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
return Arg;
case TemplateArgument::Declaration: {
- ValueDecl *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
+ auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
return TemplateArgument(D, Arg.getParamTypeForDecl());
}
@@ -5087,8 +5246,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
if (Arg.pack_size() == 0)
return Arg;
- TemplateArgument *CanonArgs
- = new (*this) TemplateArgument[Arg.pack_size()];
+ auto *CanonArgs = new (*this) TemplateArgument[Arg.pack_size()];
unsigned Idx = 0;
for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
AEnd = Arg.pack_end();
@@ -5139,7 +5297,7 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// types, e.g.,
// typedef typename T::type T1;
// typedef typename T1::type T2;
- if (const DependentNameType *DNT = T->getAs<DependentNameType>())
+ if (const auto *DNT = T->getAs<DependentNameType>())
return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
const_cast<IdentifierInfo *>(DNT->getIdentifier()));
@@ -5163,7 +5321,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the non-qualified case efficiently.
if (!T.hasLocalQualifiers()) {
// Handle the common positive case fast.
- if (const ArrayType *AT = dyn_cast<ArrayType>(T))
+ if (const auto *AT = dyn_cast<ArrayType>(T))
return AT;
}
@@ -5183,7 +5341,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
Qualifiers qs = split.Quals;
// If we have a simple case, just return now.
- const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
+ const auto *ATy = dyn_cast<ArrayType>(split.Ty);
if (!ATy || qs.empty())
return ATy;
@@ -5191,17 +5349,16 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// qualifiers into the array element type and return a new array type.
QualType NewEltTy = getQualifiedType(ATy->getElementType(), qs);
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(ATy))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(ATy))
return cast<ArrayType>(getConstantArrayType(NewEltTy, CAT->getSize(),
CAT->getSizeModifier(),
CAT->getIndexTypeCVRQualifiers()));
- if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(ATy))
+ if (const auto *IAT = dyn_cast<IncompleteArrayType>(ATy))
return cast<ArrayType>(getIncompleteArrayType(NewEltTy,
IAT->getSizeModifier(),
IAT->getIndexTypeCVRQualifiers()));
- if (const DependentSizedArrayType *DSAT
- = dyn_cast<DependentSizedArrayType>(ATy))
+ if (const auto *DSAT = dyn_cast<DependentSizedArrayType>(ATy))
return cast<ArrayType>(
getDependentSizedArrayType(NewEltTy,
DSAT->getSizeExpr(),
@@ -5209,7 +5366,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
DSAT->getIndexTypeCVRQualifiers(),
DSAT->getBracketsRange()));
- const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
+ const auto *VAT = cast<VariableArrayType>(ATy);
return cast<ArrayType>(getVariableArrayType(NewEltTy,
VAT->getSizeExpr(),
VAT->getSizeModifier(),
@@ -5303,7 +5460,7 @@ ASTContext::getConstantArrayElementCount(const ConstantArrayType *CA) const {
/// getFloatingRank - Return a relative rank for floating point types.
/// This routine will assert if passed a built-in type that isn't a float.
static FloatingRank getFloatingRank(QualType T) {
- if (const ComplexType *CT = T->getAs<ComplexType>())
+ if (const auto *CT = T->getAs<ComplexType>())
return getFloatingRank(CT->getElementType());
assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
@@ -5396,14 +5553,20 @@ unsigned ASTContext::getIntegerRank(const Type *T) const {
}
}
-/// \brief Whether this is a promotable bitfield reference according
+/// Whether this is a promotable bitfield reference according
/// to C99 6.3.1.1p2, bullet 2 (and GCC extensions).
///
/// \returns the type this bit-field will promote to, or NULL if no
/// promotion occurs.
QualType ASTContext::isPromotableBitField(Expr *E) const {
if (E->isTypeDependent() || E->isValueDependent())
- return QualType();
+ return {};
+
+ // C++ [conv.prom]p5:
+ // If the bit-field has an enumerated type, it is treated as any other
+ // value of that type for promotion purposes.
+ if (getLangOpts().CPlusPlus && E->getType()->isEnumeralType())
+ return {};
// FIXME: We should not do this unless E->refersToBitField() is true. This
// matters in C where getSourceBitField() will find bit-fields for various
@@ -5411,7 +5574,7 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
FieldDecl *Field = E->getSourceBitField(); // FIXME: conditional bit-fields?
if (!Field)
- return QualType();
+ return {};
QualType FT = Field->getType();
@@ -5431,18 +5594,20 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
//
// FIXME: C does not permit promotion of a 'long : 3' bitfield to int.
// We perform that promotion here to match GCC and C++.
+ // FIXME: C does not permit promotion of an enum bit-field whose rank is
+ // greater than that of 'int'. We perform that promotion to match GCC.
if (BitWidth < IntSize)
return IntTy;
if (BitWidth == IntSize)
return FT->isSignedIntegerType() ? IntTy : UnsignedIntTy;
- // Types bigger than int are not subject to promotions, and therefore act
+ // Bit-fields wider than int are not subject to promotions, and therefore act
// like the base type. GCC has some weird bugs in this area that we
// deliberately do not follow (GCC follows a pre-standard resolution to
// C's DR315 which treats bit-width as being part of the type, and this leaks
// into their semantics in some cases).
- return QualType();
+ return {};
}
/// getPromotedIntegerType - Returns the type that Promotable will
@@ -5451,10 +5616,10 @@ QualType ASTContext::isPromotableBitField(Expr *E) const {
QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
assert(!Promotable.isNull());
assert(Promotable->isPromotableIntegerType());
- if (const EnumType *ET = Promotable->getAs<EnumType>())
+ if (const auto *ET = Promotable->getAs<EnumType>())
return ET->getDecl()->getPromotionType();
- if (const BuiltinType *BT = Promotable->getAs<BuiltinType>()) {
+ if (const auto *BT = Promotable->getAs<BuiltinType>()) {
// C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t
// (3.9.1) can be converted to a prvalue of the first of the following
// types that can represent all the values of its underlying type:
@@ -5463,6 +5628,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
// FIXME: Is there some better way to compute this?
if (BT->getKind() == BuiltinType::WChar_S ||
BT->getKind() == BuiltinType::WChar_U ||
+ BT->getKind() == BuiltinType::Char8 ||
BT->getKind() == BuiltinType::Char16 ||
BT->getKind() == BuiltinType::Char32) {
bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S;
@@ -5489,7 +5655,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
return (PromotableSize != IntSize) ? IntTy : UnsignedIntTy;
}
-/// \brief Recurses in pointer/array types until it finds an objc retainable
+/// Recurses in pointer/array types until it finds an objc retainable
/// type and returns its ownership.
Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
while (!T.isNull()) {
@@ -5497,9 +5663,9 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
return T.getObjCLifetime();
if (T->isArrayType())
T = getBaseElementType(T);
- else if (const PointerType *PT = T->getAs<PointerType>())
+ else if (const auto *PT = T->getAs<PointerType>())
T = PT->getPointeeType();
- else if (const ReferenceType *RT = T->getAs<ReferenceType>())
+ else if (const auto *RT = T->getAs<ReferenceType>())
T = RT->getPointeeType();
else
break;
@@ -5524,9 +5690,9 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
const Type *RHSC = getCanonicalType(RHS).getTypePtr();
// Unwrap enums to their underlying type.
- if (const EnumType *ET = dyn_cast<EnumType>(LHSC))
+ if (const auto *ET = dyn_cast<EnumType>(LHSC))
LHSC = getIntegerTypeForEnum(ET);
- if (const EnumType *ET = dyn_cast<EnumType>(RHSC))
+ if (const auto *ET = dyn_cast<EnumType>(RHSC))
RHSC = getIntegerTypeForEnum(ET);
if (LHSC == RHSC) return 0;
@@ -5633,10 +5799,10 @@ QualType ASTContext::getObjCSuperType() const {
}
void ASTContext::setCFConstantStringType(QualType T) {
- const TypedefType *TD = T->getAs<TypedefType>();
+ const auto *TD = T->getAs<TypedefType>();
assert(TD && "Invalid CFConstantStringType");
CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl());
- auto TagType =
+ const auto *TagType =
CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>();
assert(TagType && "Invalid CFConstantStringType");
CFConstantStringTagDecl = TagType->getDecl();
@@ -5717,7 +5883,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
}
TargetInfo::OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const {
- auto BT = dyn_cast<BuiltinType>(T);
+ const auto *BT = dyn_cast<BuiltinType>(T);
if (!BT) {
if (isa<PipeType>(T))
@@ -5768,6 +5934,11 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
return true;
}
+ // The block needs copy/destroy helpers if Ty is non-trivial to destructively
+ // move or destroy.
+ if (Ty.isNonTrivialToPrimitiveDestructiveMove() || Ty.isDestructedType())
+ return true;
+
if (!Ty->isObjCRetainableType()) return false;
Qualifiers qs = Ty.getQualifiers();
@@ -5781,13 +5952,12 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
return false;
-
- // Tell the runtime that this is ARC __weak, called by the
- // byref routines.
+
+ // These cases should have been taken care of when checking the type's
+ // non-triviality.
case Qualifiers::OCL_Weak:
- // ARC __strong __block variables need to be retained.
case Qualifiers::OCL_Strong:
- return true;
+ llvm_unreachable("impossible");
}
llvm_unreachable("fell out of lifetime switch!");
}
@@ -5827,7 +5997,7 @@ TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {
// This returns true if a type has been typedefed to BOOL:
// typedef <type> BOOL;
static bool isTypeTypedefedAsBOOL(QualType T) {
- if (const TypedefType *TT = dyn_cast<TypedefType>(T))
+ if (const auto *TT = dyn_cast<TypedefType>(T))
if (IdentifierInfo *II = TT->getDecl()->getIdentifier())
return II->isStr("BOOL");
@@ -5879,8 +6049,7 @@ ASTContext::getInlineVariableDefinitionKind(const VarDecl *VD) const {
return InlineVariableDefinitionKind::WeakUnknown;
}
-static inline
-std::string charUnitsToString(const CharUnits &CU) {
+static std::string charUnitsToString(const CharUnits &CU) {
return llvm::itostr(CU.getQuantity());
}
@@ -5921,8 +6090,8 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
ParmOffset = PtrSize;
for (auto PVDecl : Decl->parameters()) {
QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
@@ -5964,8 +6133,8 @@ ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl) const {
// Argument types.
for (auto PVDecl : Decl->parameters()) {
QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
@@ -6034,8 +6203,8 @@ std::string ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
E = Decl->sel_param_end(); PI != E; ++PI) {
const ParmVarDecl *PVDecl = *PI;
QualType PType = PVDecl->getOriginalType();
- if (const ArrayType *AT =
- dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
+ if (const auto *AT =
+ dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
// Use array's original type only if it has known number of
// elements.
if (!isa<ConstantArrayType>(AT))
@@ -6057,13 +6226,12 @@ ASTContext::getObjCPropertyImplDeclForPropertyDecl(
const Decl *Container) const {
if (!Container)
return nullptr;
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(Container)) {
+ if (const auto *CID = dyn_cast<ObjCCategoryImplDecl>(Container)) {
for (auto *PID : CID->property_impls())
if (PID->getPropertyDecl() == PD)
return PID;
} else {
- const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+ const auto *OID = cast<ObjCImplementationDecl>(Container);
for (auto *PID : OID->property_impls())
if (PID->getPropertyDecl() == PD)
return PID;
@@ -6170,7 +6338,7 @@ ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
/// '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>()) {
+ if (const auto *BT = PointeeTy->getAs<BuiltinType>()) {
if (BT->getKind() == BuiltinType::ULong && getIntWidth(PointeeTy) == 32)
PointeeTy = UnsignedIntTy;
else
@@ -6207,6 +6375,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
switch (kind) {
case BuiltinType::Void: return 'v';
case BuiltinType::Bool: return 'B';
+ case BuiltinType::Char8:
case BuiltinType::Char_U:
case BuiltinType::UChar: return 'C';
case BuiltinType::Char16:
@@ -6235,6 +6404,30 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
+ case BuiltinType::ShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::LongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatShortAccum:
+ case BuiltinType::SatAccum:
+ case BuiltinType::SatLongAccum:
+ case BuiltinType::SatUShortAccum:
+ case BuiltinType::SatUAccum:
+ case BuiltinType::SatULongAccum:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::SatFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::SatULongFract:
// FIXME: potentially need @encodes for these!
return ' ';
@@ -6270,7 +6463,7 @@ static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {
return 'i';
// The encoding of a fixed enum type matches its fixed underlying type.
- const BuiltinType *BT = Enum->getIntegerType()->castAs<BuiltinType>();
+ const auto *BT = Enum->getIntegerType()->castAs<BuiltinType>();
return getObjCEncodingForPrimitiveKind(C, BT->getKind());
}
@@ -6307,10 +6500,10 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
S += llvm::utostr(Offset);
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
S += ObjCEncodingForEnumType(Ctx, ET);
else {
- const BuiltinType *BT = T->castAs<BuiltinType>();
+ const auto *BT = T->castAs<BuiltinType>();
S += getObjCEncodingForPrimitiveKind(Ctx, BT->getKind());
}
}
@@ -6335,21 +6528,21 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Enum:
if (FD && FD->isBitField())
return EncodeBitField(this, S, T, FD);
- if (const BuiltinType *BT = dyn_cast<BuiltinType>(CT))
+ if (const auto *BT = dyn_cast<BuiltinType>(CT))
S += getObjCEncodingForPrimitiveKind(this, BT->getKind());
else
S += ObjCEncodingForEnumType(this, cast<EnumType>(CT));
return;
case Type::Complex: {
- const ComplexType *CT = T->castAs<ComplexType>();
+ const auto *CT = T->castAs<ComplexType>();
S += 'j';
getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr);
return;
}
case Type::Atomic: {
- const AtomicType *AT = T->castAs<AtomicType>();
+ const auto *AT = T->castAs<AtomicType>();
S += 'A';
getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr);
return;
@@ -6361,7 +6554,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::RValueReference: {
QualType PointeeTy;
if (isa<PointerType>(CT)) {
- const PointerType *PT = T->castAs<PointerType>();
+ const auto *PT = T->castAs<PointerType>();
if (PT->isObjCSelType()) {
S += ':';
return;
@@ -6405,7 +6598,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '*';
return;
}
- } else if (const RecordType *RTy = PointeeTy->getAs<RecordType>()) {
+ } else if (const auto *RTy = PointeeTy->getAs<RecordType>()) {
// GCC binary compat: Need to convert "struct objc_class *" to "#".
if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) {
S += '#';
@@ -6430,7 +6623,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray: {
- const ArrayType *AT = cast<ArrayType>(CT);
+ const auto *AT = cast<ArrayType>(CT);
if (isa<IncompleteArrayType>(AT) && !StructField) {
// Incomplete arrays are encoded as a pointer to the array element.
@@ -6441,7 +6634,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
} else {
S += '[';
- if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+ if (const auto *CAT = dyn_cast<ConstantArrayType>(AT))
S += llvm::utostr(CAT->getSize().getZExtValue());
else {
//Variable length arrays are encoded as a regular array with 0 elements.
@@ -6470,8 +6663,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
S += II->getName();
- if (ClassTemplateSpecializationDecl *Spec
- = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
+ if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RDecl)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
llvm::raw_string_ostream OS(S);
printTemplateArgumentList(OS, TemplateArgs.asArray(),
@@ -6513,10 +6705,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
case Type::BlockPointer: {
- const BlockPointerType *BT = T->castAs<BlockPointerType>();
+ const auto *BT = T->castAs<BlockPointerType>();
S += "@?"; // Unlike a pointer-to-function, which is "^?".
if (EncodeBlockParameters) {
- const FunctionType *FT = BT->getPointeeType()->castAs<FunctionType>();
+ const auto *FT = BT->getPointeeType()->castAs<FunctionType>();
S += '<';
// Block return type
@@ -6528,7 +6720,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Block self
S += "@?";
// Block parameters
- if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
+ if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {
for (const auto &I : FPT->param_types())
getObjCEncodingForTypeImpl(
I, S, ExpandPointedToStructures, ExpandStructures, FD,
@@ -6552,7 +6744,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += "{objc_class=}";
return;
}
- // TODO: Double check to make sure this intentially falls through.
+ // TODO: Double check to make sure this intentionally falls through.
LLVM_FALLTHROUGH;
}
@@ -6567,7 +6759,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
- const FieldDecl *Field = cast<FieldDecl>(Ivars[i]);
+ const FieldDecl *Field = Ivars[i];
if (Field->isBitField())
getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
else
@@ -6582,7 +6774,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
case Type::ObjCObjectPointer: {
- const ObjCObjectPointerType *OPT = T->castAs<ObjCObjectPointerType>();
+ const auto *OPT = T->castAs<ObjCObjectPointerType>();
if (OPT->isObjCIdType()) {
S += '@';
return;
@@ -6591,7 +6783,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
// FIXME: Consider if we need to output qualifiers for 'Class<p>'.
// Since this is a binary compatibility issue, need to consult with runtime
- // folks. Fortunately, this is a *very* obsure construct.
+ // folks. Fortunately, this is a *very* obscure construct.
S += '#';
return;
}
@@ -6628,7 +6820,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
- if (cast<FieldDecl>(Ivars[i]) == FD) {
+ if (Ivars[i] == FD) {
S += '{';
S += OI->getObjCRuntimeNameAsString();
S += '}';
@@ -6702,7 +6894,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (!RDecl->getDefinition() || RDecl->getDefinition()->isInvalidDecl())
return;
- CXXRecordDecl *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
+ const auto *CXXRec = dyn_cast<CXXRecordDecl>(RDecl);
std::multimap<uint64_t, NamedDecl *> FieldOrBaseOffsets;
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
@@ -6795,7 +6987,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (!dcl)
break; // reached end of structure.
- if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
+ if (auto *base = dyn_cast<CXXRecordDecl>(dcl)) {
// We expand the bases without their virtual bases since those are going
// in the initial structure. Note that this differs from gcc which
// expands virtual bases each time one is encountered in the hierarchy,
@@ -6807,7 +6999,7 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
#endif
} else {
- FieldDecl *field = cast<FieldDecl>(dcl);
+ const auto *field = cast<FieldDecl>(dcl);
if (FD) {
S += '"';
S += field->getNameAsString();
@@ -7250,6 +7442,10 @@ TypedefDecl *ASTContext::getBuiltinMSVaListDecl() const {
return BuiltinMSVaListDecl;
}
+bool ASTContext::canBuiltinBeRedeclared(const FunctionDecl *FD) const {
+ return BuiltinInfo.canBeRedeclared(FD->getBuiltinID());
+}
+
void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
assert(ObjCConstantStringType.isNull() &&
"'NSConstantString' type already set!");
@@ -7257,7 +7453,7 @@ void ASTContext::setObjCConstantStringInterface(ObjCInterfaceDecl *Decl) {
ObjCConstantStringType = getObjCInterfaceType(Decl);
}
-/// \brief Retrieve the template name that corresponds to a non-empty
+/// Retrieve the template name that corresponds to a non-empty
/// lookup.
TemplateName
ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
@@ -7267,12 +7463,13 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
void *memory = Allocate(sizeof(OverloadedTemplateStorage) +
size * sizeof(FunctionTemplateDecl*));
- OverloadedTemplateStorage *OT = new(memory) OverloadedTemplateStorage(size);
+ auto *OT = new (memory) OverloadedTemplateStorage(size);
NamedDecl **Storage = OT->getStorage();
for (UnresolvedSetIterator I = Begin; I != End; ++I) {
NamedDecl *D = *I;
assert(isa<FunctionTemplateDecl>(D) ||
+ isa<UnresolvedUsingValueDecl>(D) ||
(isa<UsingShadowDecl>(D) &&
isa<FunctionTemplateDecl>(D->getUnderlyingDecl())));
*Storage++ = D;
@@ -7281,7 +7478,7 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
return TemplateName(OT);
}
-/// \brief Retrieve the template name that represents a qualified
+/// Retrieve the template name that represents a qualified
/// template name such as \c std::vector.
TemplateName
ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
@@ -7305,7 +7502,7 @@ ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
return TemplateName(QTN);
}
-/// \brief Retrieve the template name that represents a dependent
+/// Retrieve the template name that represents a dependent
/// template name such as \c MetaFun::template apply.
TemplateName
ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
@@ -7341,7 +7538,7 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
return TemplateName(QTN);
}
-/// \brief Retrieve the template name that represents a dependent
+/// Retrieve the template name that represents a dependent
/// template name such as \c MetaFun::template operator+.
TemplateName
ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
@@ -7399,7 +7596,7 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
TemplateName
ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
const TemplateArgument &ArgPack) const {
- ASTContext &Self = const_cast<ASTContext &>(*this);
+ auto &Self = const_cast<ASTContext &>(*this);
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
@@ -7422,7 +7619,7 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
/// is actually a value of type @c TargetInfo::IntType.
CanQualType ASTContext::getFromTargetType(unsigned Type) const {
switch (Type) {
- case TargetInfo::NoInt: return CanQualType();
+ case TargetInfo::NoInt: return {};
case TargetInfo::SignedChar: return SignedCharTy;
case TargetInfo::UnsignedChar: return UnsignedCharTy;
case TargetInfo::SignedShort: return ShortTy;
@@ -7465,7 +7662,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const {
// pointer.
#ifndef NDEBUG
QualType CT = Ty->getCanonicalTypeInternal();
- while (const ArrayType *AT = dyn_cast<ArrayType>(CT))
+ while (const auto *AT = dyn_cast<ArrayType>(CT))
CT = AT->getElementType();
assert(CT->isAnyPointerType() || CT->isBlockPointerType());
#endif
@@ -7496,8 +7693,8 @@ bool ASTContext::areCompatibleVectorTypes(QualType FirstVec,
// Treat Neon vector types and most AltiVec vector types as if they are the
// equivalent GCC vector types.
- const VectorType *First = FirstVec->getAs<VectorType>();
- const VectorType *Second = SecondVec->getAs<VectorType>();
+ const auto *First = FirstVec->getAs<VectorType>();
+ const auto *Second = SecondVec->getAs<VectorType>();
if (First->getNumElements() == Second->getNumElements() &&
hasSameType(First->getElementType(), Second->getElementType()) &&
First->getVectorKind() != VectorType::AltiVecPixel &&
@@ -7530,8 +7727,8 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
/// Class<pr1, ...>.
bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
QualType rhs) {
- const ObjCObjectPointerType *lhsQID = lhs->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *lhsQID = lhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
assert((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
for (auto *lhsProto : lhsQID->quals()) {
@@ -7561,7 +7758,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
return true;
if (const ObjCObjectPointerType *lhsQID = lhs->getAsObjCQualifiedIdType()) {
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
if (!rhsOPT) return false;
@@ -7847,14 +8044,14 @@ void getIntersectionOfProtocols(ASTContext &Context,
static bool canAssignObjCObjectTypes(ASTContext &ctx, QualType lhs,
QualType rhs) {
// Common case: two object pointers.
- const ObjCObjectPointerType *lhsOPT = lhs->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
+ const auto *lhsOPT = lhs->getAs<ObjCObjectPointerType>();
+ const auto *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
if (lhsOPT && rhsOPT)
return ctx.canAssignObjCInterfaces(lhsOPT, rhsOPT);
// Two block pointers.
- const BlockPointerType *lhsBlock = lhs->getAs<BlockPointerType>();
- const BlockPointerType *rhsBlock = rhs->getAs<BlockPointerType>();
+ const auto *lhsBlock = lhs->getAs<BlockPointerType>();
+ const auto *rhsBlock = rhs->getAs<BlockPointerType>();
if (lhsBlock && rhsBlock)
return ctx.typesAreBlockPointerCompatible(lhs, rhs);
@@ -7914,7 +8111,7 @@ QualType ASTContext::areCommonBaseCompatible(
const ObjCInterfaceDecl* RDecl = RHS->getInterface();
if (!LDecl || !RDecl)
- return QualType();
+ return {};
// When either LHS or RHS is a kindof type, we should return a kindof type.
// For example, for common base of kindof(ASub1) and kindof(ASub2), we return
@@ -7939,7 +8136,7 @@ QualType ASTContext::areCommonBaseCompatible(
if (!sameObjCTypeArgs(*this, LHS->getInterface(),
LHS->getTypeArgs(), RHS->getTypeArgs(),
/*stripKindOf=*/true))
- return QualType();
+ return {};
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
@@ -7990,7 +8187,7 @@ QualType ASTContext::areCommonBaseCompatible(
if (!sameObjCTypeArgs(*this, LHS->getInterface(),
LHS->getTypeArgs(), RHS->getTypeArgs(),
/*stripKindOf=*/true))
- return QualType();
+ return {};
} else if (LHS->isSpecialized() != RHS->isSpecialized()) {
// If only one has type arguments, the result will not have type
// arguments.
@@ -8025,7 +8222,7 @@ QualType ASTContext::areCommonBaseCompatible(
RHS = RHSSuperType->castAs<ObjCObjectType>();
}
- return QualType();
+ return {};
}
bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
@@ -8092,8 +8289,8 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
bool ASTContext::areComparableObjCPointerTypes(QualType LHS, QualType RHS) {
// get the "pointed to" types
- const ObjCObjectPointerType *LHSOPT = LHS->getAs<ObjCObjectPointerType>();
- const ObjCObjectPointerType *RHSOPT = RHS->getAs<ObjCObjectPointerType>();
+ const auto *LHSOPT = LHS->getAs<ObjCObjectPointerType>();
+ const auto *RHSOPT = RHS->getAs<ObjCObjectPointerType>();
if (!LHSOPT || !RHSOPT)
return false;
@@ -8146,7 +8343,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
}
}
- return QualType();
+ return {};
}
/// mergeFunctionParameterTypes - merge two types which appear as function
@@ -8173,10 +8370,10 @@ QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
bool OfBlockPointer,
bool Unqualified) {
- const FunctionType *lbase = lhs->getAs<FunctionType>();
- const FunctionType *rbase = rhs->getAs<FunctionType>();
- const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase);
- const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase);
+ const auto *lbase = lhs->getAs<FunctionType>();
+ const auto *rbase = rhs->getAs<FunctionType>();
+ const auto *lproto = dyn_cast<FunctionProtoType>(lbase);
+ const auto *rproto = dyn_cast<FunctionProtoType>(rbase);
bool allLTypes = true;
bool allRTypes = true;
@@ -8193,7 +8390,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
else
retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
Unqualified);
- if (retType.isNull()) return QualType();
+ if (retType.isNull())
+ return {};
if (Unqualified)
retType = retType.getUnqualifiedType();
@@ -8219,18 +8417,20 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Compatible functions must have compatible calling conventions
if (lbaseInfo.getCC() != rbaseInfo.getCC())
- return QualType();
+ return {};
// Regparm is part of the calling convention.
if (lbaseInfo.getHasRegParm() != rbaseInfo.getHasRegParm())
- return QualType();
+ return {};
if (lbaseInfo.getRegParm() != rbaseInfo.getRegParm())
- return QualType();
+ return {};
if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
- return QualType();
+ return {};
if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs())
- return QualType();
+ return {};
+ if (lbaseInfo.getNoCfCheck() != rbaseInfo.getNoCfCheck())
+ return {};
// FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
@@ -8247,20 +8447,20 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
"C++ shouldn't be here");
// Compatible functions must have the same number of parameters
if (lproto->getNumParams() != rproto->getNumParams())
- return QualType();
+ return {};
// Variadic and non-variadic functions aren't compatible
if (lproto->isVariadic() != rproto->isVariadic())
- return QualType();
+ return {};
if (lproto->getTypeQuals() != rproto->getTypeQuals())
- return QualType();
+ return {};
SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;
bool canUseLeft, canUseRight;
if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight,
newParamInfos))
- return QualType();
+ return {};
if (!canUseLeft)
allLTypes = false;
@@ -8275,7 +8475,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
QualType paramType = mergeFunctionParameterTypes(
lParamType, rParamType, OfBlockPointer, Unqualified);
if (paramType.isNull())
- return QualType();
+ return {};
if (Unqualified)
paramType = paramType.getUnqualifiedType();
@@ -8308,7 +8508,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
const FunctionProtoType *proto = lproto ? lproto : rproto;
if (proto) {
assert(!proto->hasExceptionSpec() && "C++ shouldn't be here");
- if (proto->isVariadic()) return QualType();
+ if (proto->isVariadic())
+ return {};
// Check that the types are compatible with the types that
// would result from default argument promotions (C99 6.7.5.3p15).
// The only types actually affected are promotable integer
@@ -8319,15 +8520,15 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Look at the converted type of enum types, since that is the type used
// to pass enum values.
- if (const EnumType *Enum = paramTy->getAs<EnumType>()) {
+ if (const auto *Enum = paramTy->getAs<EnumType>()) {
paramTy = Enum->getDecl()->getIntegerType();
if (paramTy.isNull())
- return QualType();
+ return {};
}
if (paramTy->isPromotableIntegerType() ||
getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
- return QualType();
+ return {};
}
if (allLTypes) return lhs;
@@ -8351,7 +8552,8 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
// Compatibility is based on the underlying type, not the promotion
// type.
QualType underlyingType = ET->getDecl()->getIntegerType();
- if (underlyingType.isNull()) return QualType();
+ if (underlyingType.isNull())
+ return {};
if (Context.hasSameType(underlyingType, other))
return other;
@@ -8361,7 +8563,7 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
Context.getTypeSize(underlyingType) == Context.getTypeSize(other))
return other;
- return QualType();
+ return {};
}
QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
@@ -8397,7 +8599,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
LQuals.getAddressSpace() != RQuals.getAddressSpace() ||
LQuals.getObjCLifetime() != RQuals.getObjCLifetime() ||
LQuals.hasUnaligned() != RQuals.hasUnaligned())
- return QualType();
+ return {};
// Exactly one GC qualifier difference is allowed: __strong is
// okay if the other type has no GC qualifier but is an Objective
@@ -8409,7 +8611,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
- return QualType();
+ return {};
if (GC_L == Qualifiers::Strong && RHSCan->isObjCObjectPointerType()) {
return mergeTypes(LHS, getObjCGCQualType(RHS, Qualifiers::Strong));
@@ -8417,7 +8619,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (GC_R == Qualifiers::Strong && LHSCan->isObjCObjectPointerType()) {
return mergeTypes(getObjCGCQualType(LHS, Qualifiers::Strong), RHS);
}
- return QualType();
+ return {};
}
// Okay, qualifiers are equal.
@@ -8448,7 +8650,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
if (LHSClass != RHSClass) {
// Note that we only have special rules for turning block enum
// returns into block int returns, not vice-versa.
- if (const EnumType* ETy = LHS->getAs<EnumType>()) {
+ if (const auto *ETy = LHS->getAs<EnumType>()) {
return mergeEnumWithInteger(*this, ETy, RHS, false);
}
if (const EnumType* ETy = RHS->getAs<EnumType>()) {
@@ -8462,7 +8664,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return RHS;
}
- return QualType();
+ return {};
}
// The canonical type classes match.
@@ -8500,7 +8702,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
}
QualType ResultType = mergeTypes(LHSPointee, RHSPointee, false,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
@@ -8522,7 +8725,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
// Blocks can't be an expression in a ternary operator (OpenCL v2.0
// 6.12.5) thus the following check is asymmetric.
if (!LHSPteeQual.isAddressSpaceSupersetOf(RHSPteeQual))
- return QualType();
+ return {};
LHSPteeQual.removeAddressSpace();
RHSPteeQual.removeAddressSpace();
LHSPointee =
@@ -8532,7 +8735,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
}
QualType ResultType = mergeTypes(LHSPointee, RHSPointee, OfBlockPointer,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSPointee) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSPointee) == getCanonicalType(ResultType))
@@ -8550,7 +8754,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
}
QualType ResultType = mergeTypes(LHSValue, RHSValue, false,
Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
if (getCanonicalType(LHSValue) == getCanonicalType(ResultType))
return LHS;
if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))
@@ -8562,7 +8767,7 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
const ConstantArrayType* RCAT = getAsConstantArrayType(RHS);
if (LCAT && RCAT && RCAT->getSize() != LCAT->getSize())
- return QualType();
+ return {};
QualType LHSElem = getAsArrayType(LHS)->getElementType();
QualType RHSElem = getAsArrayType(RHS)->getElementType();
@@ -8572,7 +8777,40 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
}
QualType ResultType = mergeTypes(LHSElem, RHSElem, false, Unqualified);
- if (ResultType.isNull()) return QualType();
+ if (ResultType.isNull())
+ return {};
+
+ const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
+ const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
+
+ // If either side is a variable array, and both are complete, check whether
+ // the current dimension is definite.
+ if (LVAT || RVAT) {
+ auto SizeFetch = [this](const VariableArrayType* VAT,
+ const ConstantArrayType* CAT)
+ -> std::pair<bool,llvm::APInt> {
+ if (VAT) {
+ llvm::APSInt TheInt;
+ Expr *E = VAT->getSizeExpr();
+ if (E && E->isIntegerConstantExpr(TheInt, *this))
+ return std::make_pair(true, TheInt);
+ else
+ return std::make_pair(false, TheInt);
+ } else if (CAT) {
+ return std::make_pair(true, CAT->getSize());
+ } else {
+ return std::make_pair(false, llvm::APInt());
+ }
+ };
+
+ bool HaveLSize, HaveRSize;
+ llvm::APInt LSize, RSize;
+ std::tie(HaveLSize, LSize) = SizeFetch(LVAT, LCAT);
+ std::tie(HaveRSize, RSize) = SizeFetch(RVAT, RCAT);
+ if (HaveLSize && HaveRSize && !llvm::APInt::isSameValue(LSize, RSize))
+ return {}; // Definite, but unequal, array dimension
+ }
+
if (LCAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RCAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
@@ -8581,8 +8819,6 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
ArrayType::ArraySizeModifier(), 0);
if (RCAT) return getConstantArrayType(ResultType, RCAT->getSize(),
ArrayType::ArraySizeModifier(), 0);
- const VariableArrayType* LVAT = getAsVariableArrayType(LHS);
- const VariableArrayType* RVAT = getAsVariableArrayType(RHS);
if (LVAT && getCanonicalType(LHSElem) == getCanonicalType(ResultType))
return LHS;
if (RVAT && getCanonicalType(RHSElem) == getCanonicalType(ResultType))
@@ -8608,29 +8844,29 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return mergeFunctionTypes(LHS, RHS, OfBlockPointer, Unqualified);
case Type::Record:
case Type::Enum:
- return QualType();
+ return {};
case Type::Builtin:
// Only exactly equal builtin types are compatible, which is tested above.
- return QualType();
+ return {};
case Type::Complex:
// Distinct complex types are incompatible.
- return QualType();
+ return {};
case Type::Vector:
// FIXME: The merged type should be an ExtVector!
if (areCompatVectorTypes(LHSCan->getAs<VectorType>(),
RHSCan->getAs<VectorType>()))
return LHS;
- return QualType();
+ return {};
case Type::ObjCObject: {
// Check if the types are assignment compatible.
// FIXME: This should be type compatibility, e.g. whether
// "LHS x; RHS x;" at global scope is legal.
- const ObjCObjectType* LHSIface = LHS->getAs<ObjCObjectType>();
- const ObjCObjectType* RHSIface = RHS->getAs<ObjCObjectType>();
+ const auto *LHSIface = LHS->getAs<ObjCObjectType>();
+ const auto *RHSIface = RHS->getAs<ObjCObjectType>();
if (canAssignObjCInterfaces(LHSIface, RHSIface))
return LHS;
- return QualType();
+ return {};
}
case Type::ObjCObjectPointer:
if (OfBlockPointer) {
@@ -8639,17 +8875,17 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
RHS->getAs<ObjCObjectPointerType>(),
BlockReturnType))
return LHS;
- return QualType();
+ return {};
}
if (canAssignObjCInterfaces(LHS->getAs<ObjCObjectPointerType>(),
RHS->getAs<ObjCObjectPointerType>()))
return LHS;
- return QualType();
+ return {};
case Type::Pipe:
assert(LHS != RHS &&
"Equivalent pipe types should have already been handled!");
- return QualType();
+ return {};
}
llvm_unreachable("Invalid Type::Class!");
@@ -8717,7 +8953,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
return LHS;
if (RHSCan->isFunctionType()) {
if (!LHSCan->isFunctionType())
- return QualType();
+ return {};
QualType OldReturnType =
cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();
QualType NewReturnType =
@@ -8725,12 +8961,12 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
QualType ResReturnType =
mergeObjCGCQualifiers(NewReturnType, OldReturnType);
if (ResReturnType.isNull())
- return QualType();
+ return {};
if (ResReturnType == NewReturnType || ResReturnType == OldReturnType) {
// id foo(); ... __strong id foo(); or: __strong id foo(); ... id foo();
// In either case, use OldReturnType to build the new function type.
- const FunctionType *F = LHS->getAs<FunctionType>();
- if (const FunctionProtoType *FPT = cast<FunctionProtoType>(F)) {
+ const auto *F = LHS->getAs<FunctionType>();
+ if (const auto *FPT = cast<FunctionProtoType>(F)) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = getFunctionExtInfo(LHS);
QualType ResultType =
@@ -8738,7 +8974,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
return ResultType;
}
}
- return QualType();
+ return {};
}
// If the qualifiers are different, the types can still be merged.
@@ -8748,7 +8984,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
// If any of these qualifiers are different, we have a type mismatch.
if (LQuals.getCVRQualifiers() != RQuals.getCVRQualifiers() ||
LQuals.getAddressSpace() != RQuals.getAddressSpace())
- return QualType();
+ return {};
// Exactly one GC qualifier difference is allowed: __strong is
// okay if the other type has no GC qualifier but is an Objective
@@ -8760,13 +8996,13 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
assert((GC_L != GC_R) && "unequal qualifier sets had only equal elements");
if (GC_L == Qualifiers::Weak || GC_R == Qualifiers::Weak)
- return QualType();
+ return {};
if (GC_L == Qualifiers::Strong)
return LHS;
if (GC_R == Qualifiers::Strong)
return RHS;
- return QualType();
+ return {};
}
if (LHSCan->isObjCObjectPointerType() && RHSCan->isObjCObjectPointerType()) {
@@ -8778,7 +9014,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
if (ResQT == RHSBaseQT)
return RHS;
}
- return QualType();
+ return {};
}
//===----------------------------------------------------------------------===//
@@ -8786,7 +9022,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
//===----------------------------------------------------------------------===//
unsigned ASTContext::getIntWidth(QualType T) const {
- if (const EnumType *ET = T->getAs<EnumType>())
+ if (const auto *ET = T->getAs<EnumType>())
T = ET->getDecl()->getIntegerType();
if (T->isBooleanType())
return 1;
@@ -8795,19 +9031,20 @@ unsigned ASTContext::getIntWidth(QualType T) const {
}
QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
- assert(T->hasSignedIntegerRepresentation() && "Unexpected type");
+ assert((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&
+ "Unexpected type");
// Turn <4 x signed int> -> <4 x unsigned int>
- if (const VectorType *VTy = T->getAs<VectorType>())
+ if (const auto *VTy = T->getAs<VectorType>())
return getVectorType(getCorrespondingUnsignedType(VTy->getElementType()),
VTy->getNumElements(), VTy->getVectorKind());
// For enums, we return the unsigned version of the base type.
- if (const EnumType *ETy = T->getAs<EnumType>())
+ if (const auto *ETy = T->getAs<EnumType>())
T = ETy->getDecl()->getIntegerType();
- const BuiltinType *BTy = T->getAs<BuiltinType>();
- assert(BTy && "Unexpected signed integer type");
+ const auto *BTy = T->getAs<BuiltinType>();
+ assert(BTy && "Unexpected signed integer or fixed point type");
switch (BTy->getKind()) {
case BuiltinType::Char_S:
case BuiltinType::SChar:
@@ -8822,8 +9059,33 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
return UnsignedLongLongTy;
case BuiltinType::Int128:
return UnsignedInt128Ty;
+
+ case BuiltinType::ShortAccum:
+ return UnsignedShortAccumTy;
+ case BuiltinType::Accum:
+ return UnsignedAccumTy;
+ case BuiltinType::LongAccum:
+ return UnsignedLongAccumTy;
+ case BuiltinType::SatShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::SatAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::SatLongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return UnsignedShortFractTy;
+ case BuiltinType::Fract:
+ return UnsignedFractTy;
+ case BuiltinType::LongFract:
+ return UnsignedLongFractTy;
+ case BuiltinType::SatShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::SatFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::SatLongFract:
+ return SatUnsignedLongFractTy;
default:
- llvm_unreachable("Unexpected signed integer type");
+ llvm_unreachable("Unexpected signed integer or fixed point type");
}
}
@@ -8931,10 +9193,12 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Type = Context.FloatTy;
break;
case 'd':
- assert(HowLong < 2 && !Signed && !Unsigned &&
+ assert(HowLong < 3 && !Signed && !Unsigned &&
"Bad modifiers used with 'd'!");
- if (HowLong)
+ if (HowLong == 1)
Type = Context.LongDoubleTy;
+ else if (HowLong == 2)
+ Type = Context.Float128Ty;
else
Type = Context.DoubleTy;
break;
@@ -9050,7 +9314,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Type = Context.getFILEType();
if (Type.isNull()) {
Error = ASTContext::GE_Missing_stdio;
- return QualType();
+ return {};
}
break;
case 'J':
@@ -9061,7 +9325,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
if (Type.isNull()) {
Error = ASTContext::GE_Missing_setjmp;
- return QualType();
+ return {};
}
break;
case 'K':
@@ -9070,7 +9334,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
if (Type.isNull()) {
Error = ASTContext::GE_Missing_ucontext;
- return QualType();
+ return {};
}
break;
case 'p':
@@ -9132,14 +9396,14 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
QualType ResType = DecodeTypeFromStr(TypeStr, *this, Error,
RequiresICE, true);
if (Error != GE_None)
- return QualType();
+ return {};
assert(!RequiresICE && "Result of intrinsic cannot be required to be an ICE");
while (TypeStr[0] && TypeStr[0] != '.') {
QualType Ty = DecodeTypeFromStr(TypeStr, *this, Error, RequiresICE, true);
if (Error != GE_None)
- return QualType();
+ return {};
// If this argument is required to be an IntegerConstantExpression and the
// caller cares, fill in the bitmask we return.
@@ -9154,7 +9418,7 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
}
if (Id == Builtin::BI__GetExceptionInfo)
- return QualType();
+ return {};
assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
"'.' should only occur at end of builtin type list!");
@@ -9185,7 +9449,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
// 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 (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
if (!MD->isUserProvided())
return GVA_DiscardableODR;
@@ -9240,6 +9504,21 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
return GVA_DiscardableODR;
}
+static bool isDeclareTargetToDeclaration(const Decl *VD) {
+ for (const Decl *D : VD->redecls()) {
+ if (!D->hasAttrs())
+ continue;
+ if (const auto *Attr = D->getAttr<OMPDeclareTargetDeclAttr>())
+ return Attr->getMapType() == OMPDeclareTargetDeclAttr::MT_To;
+ }
+ if (const auto *V = dyn_cast<VarDecl>(VD)) {
+ if (const VarDecl *TD = V->getTemplateInstantiationPattern())
+ return isDeclareTargetToDeclaration(TD);
+ }
+
+ return false;
+}
+
static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
const Decl *D, GVALinkage L) {
// See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
@@ -9256,6 +9535,12 @@ static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
// visible externally so they can be launched from host.
if (L == GVA_DiscardableODR || L == GVA_Internal)
return GVA_StrongODR;
+ } else if (Context.getLangOpts().OpenMP && Context.getLangOpts().OpenMPIsDevice &&
+ isDeclareTargetToDeclaration(D)) {
+ // Static variables must be visible externally so they can be mapped from
+ // host.
+ if (L == GVA_Internal)
+ return GVA_StrongODR;
}
return L;
}
@@ -9375,7 +9660,7 @@ GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
}
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
if (!VD->isFileVarDecl())
return false;
// Global named register variables (GNU extension) are never emitted.
@@ -9384,14 +9669,13 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (VD->getDescribedVarTemplate() ||
isa<VarTemplatePartialSpecializationDecl>(VD))
return false;
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// We never need to emit an uninstantiated function template.
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
return false;
} else if (isa<PragmaCommentDecl>(D))
return true;
- else if (isa<OMPThreadPrivateDecl>(D) ||
- D->hasAttr<OMPDeclareTargetDeclAttr>())
+ else if (isa<OMPThreadPrivateDecl>(D))
return true;
else if (isa<PragmaDetectMismatchDecl>(D))
return true;
@@ -9404,6 +9688,29 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
else
return false;
+ if (D->isFromASTFile() && !LangOpts.BuildingPCHWithObjectFile) {
+ assert(getExternalSource() && "It's from an AST file; must have a source.");
+ // On Windows, PCH files are built together with an object file. If this
+ // declaration comes from such a PCH and DeclMustBeEmitted would return
+ // true, it would have returned true and the decl would have been emitted
+ // into that object file, so it doesn't need to be emitted here.
+ // Note that decls are still emitted if they're referenced, as usual;
+ // DeclMustBeEmitted is used to decide whether a decl must be emitted even
+ // if it's not referenced.
+ //
+ // Explicit template instantiation definitions are tricky. If there was an
+ // explicit template instantiation decl in the PCH before, it will look like
+ // the definition comes from there, even if that was just the declaration.
+ // (Explicit instantiation defs of variable templates always get emitted.)
+ bool IsExpInstDef =
+ isa<FunctionDecl>(D) &&
+ cast<FunctionDecl>(D)->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+
+ if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef)
+ return false;
+ }
+
// If this is a member of a class template, we do not need to emit it.
if (D->getDeclContext()->isDependentContext())
return false;
@@ -9416,7 +9723,7 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (D->hasAttr<AliasAttr>() || D->hasAttr<UsedAttr>())
return true;
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
// Forward declarations aren't required.
if (!FD->doesThisDeclarationHaveABody())
return FD->doesDeclarationForceExternallyVisibleDefinition();
@@ -9424,11 +9731,11 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Constructors and destructors are required.
if (FD->hasAttr<ConstructorAttr>() || FD->hasAttr<DestructorAttr>())
return true;
-
+
// The key function for a class is required. This rule only comes
// into play when inline functions can be key functions, though.
if (getTargetInfo().getCXXABI().canKeyFunctionBeInline()) {
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
const CXXRecordDecl *RD = MD->getParent();
if (MD->isOutOfLine() && RD->isDynamicClass()) {
const CXXMethodDecl *KeyFunc = getCurrentKeyFunction(RD);
@@ -9445,8 +9752,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Implicit template instantiations can also be deferred in C++.
return !isDiscardableGVALinkage(Linkage);
}
-
- const VarDecl *VD = cast<VarDecl>(D);
+
+ const auto *VD = cast<VarDecl>(D);
assert(VD->isFileVarDecl() && "Expected file scoped var");
if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
@@ -9474,15 +9781,41 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// Likewise, variables with tuple-like bindings are required if their
// bindings have side-effects.
- if (auto *DD = dyn_cast<DecompositionDecl>(VD))
- for (auto *BD : DD->bindings())
- if (auto *BindingVD = BD->getHoldingVar())
+ if (const auto *DD = dyn_cast<DecompositionDecl>(VD))
+ for (const auto *BD : DD->bindings())
+ if (const auto *BindingVD = BD->getHoldingVar())
if (DeclMustBeEmitted(BindingVD))
return true;
+ // If the decl is marked as `declare target`, it should be emitted.
+ for (const auto *Decl : D->redecls()) {
+ if (!Decl->hasAttrs())
+ continue;
+ if (const auto *Attr = Decl->getAttr<OMPDeclareTargetDeclAttr>())
+ if (Attr->getMapType() != OMPDeclareTargetDeclAttr::MT_Link)
+ return true;
+ }
+
return false;
}
+void ASTContext::forEachMultiversionedFunctionVersion(
+ const FunctionDecl *FD,
+ llvm::function_ref<void(const FunctionDecl *)> Pred) const {
+ assert(FD->isMultiVersion() && "Only valid for multiversioned functions");
+ llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls;
+ FD = FD->getCanonicalDecl();
+ for (auto *CurDecl :
+ FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) {
+ FunctionDecl *CurFD = CurDecl->getAsFunction()->getCanonicalDecl();
+ if (CurFD && hasSameType(CurFD->getType(), FD->getType()) &&
+ std::end(SeenDecls) == llvm::find(SeenDecls, CurFD)) {
+ SeenDecls.insert(CurFD);
+ Pred(CurFD);
+ }
+ }
+}
+
CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const {
// Pass through to the C++ ABI object
@@ -9595,7 +9928,7 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const {
case TargetInfo::Float128:
return Float128Ty;
case TargetInfo::NoFloat:
- return QualType();
+ return {};
}
llvm_unreachable("Unhandled TargetInfo::RealType value");
@@ -9739,7 +10072,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
}
/// @}
- /// \brief A \c RecursiveASTVisitor that builds a map from nodes to their
+ /// A \c RecursiveASTVisitor that builds a map from nodes to their
/// parents as defined by the \c RecursiveASTVisitor.
///
/// Note that the relationship described here is purely in terms of AST
@@ -9749,7 +10082,7 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
public:
- /// \brief Builds and returns the translation unit's parent map.
+ /// Builds and returns the translation unit's parent map.
///
/// The caller takes ownership of the returned \c ParentMap.
static std::pair<ASTContext::ParentMapPointers *,
@@ -9874,7 +10207,8 @@ static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
if (I == Map.end()) {
return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
}
- if (auto *V = I->second.template dyn_cast<ASTContext::ParentVector *>()) {
+ if (const auto *V =
+ I->second.template dyn_cast<ASTContext::ParentVector *>()) {
return llvm::makeArrayRef(*V);
}
return getSingleDynTypedNodeFromParentMap(I->second);
@@ -9942,6 +10276,42 @@ unsigned ASTContext::getTargetAddressSpace(LangAS AS) const {
return (*AddrSpaceMap)[(unsigned)AS];
}
+QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ if (Ty->isSaturatedFixedPointType()) return Ty;
+
+ const auto &BT = Ty->getAs<BuiltinType>();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ return SatShortAccumTy;
+ case BuiltinType::Accum:
+ return SatAccumTy;
+ case BuiltinType::LongAccum:
+ return SatLongAccumTy;
+ case BuiltinType::UShortAccum:
+ return SatUnsignedShortAccumTy;
+ case BuiltinType::UAccum:
+ return SatUnsignedAccumTy;
+ case BuiltinType::ULongAccum:
+ return SatUnsignedLongAccumTy;
+ case BuiltinType::ShortFract:
+ return SatShortFractTy;
+ case BuiltinType::Fract:
+ return SatFractTy;
+ case BuiltinType::LongFract:
+ return SatLongFractTy;
+ case BuiltinType::UShortFract:
+ return SatUnsignedShortFractTy;
+ case BuiltinType::UFract:
+ return SatUnsignedFractTy;
+ case BuiltinType::ULongFract:
+ return SatUnsignedLongFractTy;
+ }
+}
+
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
// doesn't include ASTContext.h
template
@@ -9950,3 +10320,92 @@ clang::LazyGenerationalUpdatePtr<
clang::LazyGenerationalUpdatePtr<
const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
const clang::ASTContext &Ctx, Decl *Value);
+
+unsigned char ASTContext::getFixedPointScale(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ const auto *BT = Ty->getAs<BuiltinType>();
+ const TargetInfo &Target = getTargetInfo();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ case BuiltinType::SatShortAccum:
+ return Target.getShortAccumScale();
+ case BuiltinType::Accum:
+ case BuiltinType::SatAccum:
+ return Target.getAccumScale();
+ case BuiltinType::LongAccum:
+ case BuiltinType::SatLongAccum:
+ return Target.getLongAccumScale();
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatUShortAccum:
+ return Target.getUnsignedShortAccumScale();
+ case BuiltinType::UAccum:
+ case BuiltinType::SatUAccum:
+ return Target.getUnsignedAccumScale();
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatULongAccum:
+ return Target.getUnsignedLongAccumScale();
+ case BuiltinType::ShortFract:
+ case BuiltinType::SatShortFract:
+ return Target.getShortFractScale();
+ case BuiltinType::Fract:
+ case BuiltinType::SatFract:
+ return Target.getFractScale();
+ case BuiltinType::LongFract:
+ case BuiltinType::SatLongFract:
+ return Target.getLongFractScale();
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatUShortFract:
+ return Target.getUnsignedShortFractScale();
+ case BuiltinType::UFract:
+ case BuiltinType::SatUFract:
+ return Target.getUnsignedFractScale();
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatULongFract:
+ return Target.getUnsignedLongFractScale();
+ }
+}
+
+unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+
+ const auto *BT = Ty->getAs<BuiltinType>();
+ const TargetInfo &Target = getTargetInfo();
+ switch (BT->getKind()) {
+ default:
+ llvm_unreachable("Not a fixed point type!");
+ case BuiltinType::ShortAccum:
+ case BuiltinType::SatShortAccum:
+ return Target.getShortAccumIBits();
+ case BuiltinType::Accum:
+ case BuiltinType::SatAccum:
+ return Target.getAccumIBits();
+ case BuiltinType::LongAccum:
+ case BuiltinType::SatLongAccum:
+ return Target.getLongAccumIBits();
+ case BuiltinType::UShortAccum:
+ case BuiltinType::SatUShortAccum:
+ return Target.getUnsignedShortAccumIBits();
+ case BuiltinType::UAccum:
+ case BuiltinType::SatUAccum:
+ return Target.getUnsignedAccumIBits();
+ case BuiltinType::ULongAccum:
+ case BuiltinType::SatULongAccum:
+ return Target.getUnsignedLongAccumIBits();
+ case BuiltinType::ShortFract:
+ case BuiltinType::SatShortFract:
+ case BuiltinType::Fract:
+ case BuiltinType::SatFract:
+ case BuiltinType::LongFract:
+ case BuiltinType::SatLongFract:
+ case BuiltinType::UShortFract:
+ case BuiltinType::SatUShortFract:
+ case BuiltinType::UFract:
+ case BuiltinType::SatUFract:
+ case BuiltinType::ULongFract:
+ case BuiltinType::SatULongFract:
+ return 0;
+ }
+}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index b43c28deb362..c4c0f6e5ebe3 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -200,7 +200,7 @@ break; \
return QC.apply(Context, QT);
}
-/// \brief Convert the given type to a string suitable for printing as part of
+/// Convert the given type to a string suitable for printing as part of
/// a diagnostic.
///
/// There are four main criteria when determining whether we should have an
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 92be6d95e898..f46ae58d192d 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -521,10 +521,12 @@ namespace {
// Exprs
void VisitExpr(const Expr *Node);
void VisitCastExpr(const CastExpr *Node);
+ void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
void VisitDeclRefExpr(const DeclRefExpr *Node);
void VisitPredefinedExpr(const PredefinedExpr *Node);
void VisitCharacterLiteral(const CharacterLiteral *Node);
void VisitIntegerLiteral(const IntegerLiteral *Node);
+ void VisitFixedPointLiteral(const FixedPointLiteral *Node);
void VisitFloatingLiteral(const FloatingLiteral *Node);
void VisitStringLiteral(const StringLiteral *Str);
void VisitInitListExpr(const InitListExpr *ILE);
@@ -539,6 +541,7 @@ namespace {
void VisitAddrLabelExpr(const AddrLabelExpr *Node);
void VisitBlockExpr(const BlockExpr *Node);
void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
+ void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
// C++
void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
@@ -808,11 +811,10 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
- for (auto I = Deserialize ? Primary->lookups_begin()
- : Primary->noload_lookups_begin(),
- E = Deserialize ? Primary->lookups_end()
- : Primary->noload_lookups_end();
- I != E; ++I) {
+ auto Range = Deserialize
+ ? Primary->lookups()
+ : Primary->noload_lookups(/*PreserveInternalState=*/true);
+ for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
DeclarationName Name = I.getLookupName();
DeclContextLookupResult R = *I;
@@ -1602,7 +1604,7 @@ void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
const ClassScopeFunctionSpecializationDecl *D) {
- dumpDeclRef(D->getSpecialization());
+ dumpDecl(D->getSpecialization());
if (D->hasExplicitTemplateArgs())
dumpTemplateArgumentListInfo(D->templateArgs());
}
@@ -1946,10 +1948,15 @@ void ASTDumper::dumpStmt(const Stmt *S) {
return;
}
+ // Some statements have custom mechanisms for dumping their children.
if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
VisitDeclStmt(DS);
return;
}
+ if (const GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(S)) {
+ VisitGenericSelectionExpr(GSE);
+ return;
+ }
ConstStmtVisitor<ASTDumper>::Visit(S);
@@ -2113,6 +2120,12 @@ void ASTDumper::VisitCastExpr(const CastExpr *Node) {
OS << ">";
}
+void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) {
+ VisitCastExpr(Node);
+ if (Node->isPartOfExplicitCast())
+ OS << " part_of_explicit_cast";
+}
+
void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
VisitExpr(Node);
@@ -2172,6 +2185,13 @@ void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
OS << " " << Node->getValue().toString(10, isSigned);
}
+void ASTDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
+ VisitExpr(Node);
+
+ ColorScope Color(*this, ValueColor);
+ OS << " " << Node->getValueAsString(/*Radix=*/10);
+}
+
void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
VisitExpr(Node);
ColorScope Color(*this, ValueColor);
@@ -2211,6 +2231,8 @@ void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
VisitExpr(Node);
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
<< " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
+ if (!Node->canOverflow())
+ OS << " cannot overflow";
}
void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
@@ -2272,6 +2294,32 @@ void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
dumpStmt(Source);
}
+void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
+ VisitExpr(E);
+ if (E->isResultDependent())
+ OS << " result_dependent";
+ dumpStmt(E->getControllingExpr());
+ dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove
+
+ for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
+ dumpChild([=] {
+ if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
+ OS << "case ";
+ dumpType(TSI->getType());
+ } else {
+ OS << "default";
+ }
+
+ if (!E->isResultDependent() && E->getResultIndex() == I)
+ OS << " selected";
+
+ if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I))
+ dumpTypeAsChild(TSI->getType());
+ dumpStmt(E->getAssocExpr(I));
+ });
+ }
+}
+
// GNU extensions.
void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 0d1d9807549f..6668067233e4 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1,4 +1,4 @@
-//===--- ASTImporter.cpp - Importing ASTs from other Contexts ---*- C++ -*-===//
+//===- ASTImporter.cpp - Importing ASTs from other Contexts ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,29 +11,165 @@
// context into another context.
//
//===----------------------------------------------------------------------===//
+
#include "clang/AST/ASTImporter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTStructuralEquivalence.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/DeclFriend.h"
+#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/AST/LambdaCapture.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/OperationKinds.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeVisitor.h"
+#include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <deque>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility>
namespace clang {
+
+ template <class T>
+ SmallVector<Decl*, 2>
+ getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
+ SmallVector<Decl*, 2> Redecls;
+ for (auto *R : D->getFirstDecl()->redecls()) {
+ if (R != D->getFirstDecl())
+ Redecls.push_back(R);
+ }
+ Redecls.push_back(D->getFirstDecl());
+ std::reverse(Redecls.begin(), Redecls.end());
+ return Redecls;
+ }
+
+ SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D) {
+ // Currently only FunctionDecl is supported
+ auto FD = cast<FunctionDecl>(D);
+ return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
+ }
+
+ void updateFlags(const Decl *From, Decl *To) {
+ // Check if some flags or attrs are new in 'From' and copy into 'To'.
+ // FIXME: Other flags or attrs?
+ if (From->isUsed(false) && !To->isUsed(false))
+ To->setIsUsed();
+ }
+
class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
public DeclVisitor<ASTNodeImporter, Decl *>,
public StmtVisitor<ASTNodeImporter, Stmt *> {
ASTImporter &Importer;
+ // Wrapper for an overload set.
+ template <typename ToDeclT> struct CallOverloadedCreateFun {
+ template <typename... Args>
+ auto operator()(Args &&... args)
+ -> decltype(ToDeclT::Create(std::forward<Args>(args)...)) {
+ return ToDeclT::Create(std::forward<Args>(args)...);
+ }
+ };
+
+ // Always use these functions to create a Decl during import. There are
+ // certain tasks which must be done after the Decl was created, e.g. we
+ // must immediately register that as an imported Decl. The parameter `ToD`
+ // will be set to the newly created Decl or if had been imported before
+ // then to the already imported Decl. Returns a bool value set to true if
+ // the `FromD` had been imported before.
+ template <typename ToDeclT, typename FromDeclT, typename... Args>
+ LLVM_NODISCARD bool GetImportedOrCreateDecl(ToDeclT *&ToD, FromDeclT *FromD,
+ Args &&... args) {
+ // There may be several overloads of ToDeclT::Create. We must make sure
+ // to call the one which would be chosen by the arguments, thus we use a
+ // wrapper for the overload set.
+ CallOverloadedCreateFun<ToDeclT> OC;
+ return GetImportedOrCreateSpecialDecl(ToD, OC, FromD,
+ std::forward<Args>(args)...);
+ }
+ // Use this overload if a special Type is needed to be created. E.g if we
+ // want to create a `TypeAliasDecl` and assign that to a `TypedefNameDecl`
+ // then:
+ // TypedefNameDecl *ToTypedef;
+ // GetImportedOrCreateDecl<TypeAliasDecl>(ToTypedef, FromD, ...);
+ template <typename NewDeclT, typename ToDeclT, typename FromDeclT,
+ typename... Args>
+ LLVM_NODISCARD bool GetImportedOrCreateDecl(ToDeclT *&ToD, FromDeclT *FromD,
+ Args &&... args) {
+ CallOverloadedCreateFun<NewDeclT> OC;
+ return GetImportedOrCreateSpecialDecl(ToD, OC, FromD,
+ std::forward<Args>(args)...);
+ }
+ // Use this version if a special create function must be
+ // used, e.g. CXXRecordDecl::CreateLambda .
+ template <typename ToDeclT, typename CreateFunT, typename FromDeclT,
+ typename... Args>
+ LLVM_NODISCARD bool
+ GetImportedOrCreateSpecialDecl(ToDeclT *&ToD, CreateFunT CreateFun,
+ FromDeclT *FromD, Args &&... args) {
+ ToD = cast_or_null<ToDeclT>(Importer.GetAlreadyImportedOrNull(FromD));
+ if (ToD)
+ return true; // Already imported.
+ ToD = CreateFun(std::forward<Args>(args)...);
+ InitializeImportedDecl(FromD, ToD);
+ return false; // A new Decl is created.
+ }
+
+ void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
+ Importer.MapImported(FromD, ToD);
+ ToD->IdentifierNamespace = FromD->IdentifierNamespace;
+ if (FromD->hasAttrs())
+ for (const Attr *FromAttr : FromD->getAttrs())
+ ToD->addAttr(Importer.Import(FromAttr));
+ if (FromD->isUsed())
+ ToD->setIsUsed();
+ if (FromD->isImplicit())
+ ToD->setImplicit();
+ }
+
public:
- explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) { }
-
+ explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
+
using TypeVisitor<ASTNodeImporter, QualType>::Visit;
using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
@@ -52,7 +188,7 @@ namespace clang {
QualType VisitConstantArrayType(const ConstantArrayType *T);
QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
QualType VisitVariableArrayType(const VariableArrayType *T);
- // FIXME: DependentSizedArrayType
+ QualType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
// FIXME: DependentSizedExtVectorType
QualType VisitVectorType(const VectorType *T);
QualType VisitExtVectorType(const ExtVectorType *T);
@@ -76,14 +212,15 @@ namespace clang {
QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
QualType VisitElaboratedType(const ElaboratedType *T);
- // FIXME: DependentNameType
+ QualType VisitDependentNameType(const DependentNameType *T);
QualType VisitPackExpansionType(const PackExpansionType *T);
- // FIXME: DependentTemplateSpecializationType
+ QualType VisitDependentTemplateSpecializationType(
+ const DependentTemplateSpecializationType *T);
QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
QualType VisitObjCObjectType(const ObjCObjectType *T);
QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
-
- // Importing declarations
+
+ // Importing declarations
bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
DeclContext *&LexicalDC, DeclarationName &Name,
NamedDecl *&ToD, SourceLocation &Loc);
@@ -91,22 +228,27 @@ namespace clang {
void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
DeclarationNameInfo& To);
void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
+ void ImportImplicitMethods(const CXXRecordDecl *From, CXXRecordDecl *To);
bool ImportCastPath(CastExpr *E, CXXCastPath &Path);
- typedef DesignatedInitExpr::Designator Designator;
+ using Designator = DesignatedInitExpr::Designator;
+
Designator ImportDesignator(const Designator &D);
+ Optional<LambdaCapture> ImportLambdaCapture(const LambdaCapture &From);
- /// \brief What we should import from the definition.
+ /// What we should import from the definition.
enum ImportDefinitionKind {
- /// \brief Import the default subset of the definition, which might be
+ /// Import the default subset of the definition, which might be
/// nothing (if minimal import is set) or might be everything (if minimal
/// import is not set).
IDK_Default,
- /// \brief Import everything.
+
+ /// Import everything.
IDK_Everything,
- /// \brief Import only the bare bones needed to establish a valid
+
+ /// Import only the bare bones needed to establish a valid
/// DeclContext.
IDK_Basic
};
@@ -127,16 +269,33 @@ namespace clang {
bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
ImportDefinitionKind Kind = IDK_Default);
TemplateParameterList *ImportTemplateParameterList(
- TemplateParameterList *Params);
+ TemplateParameterList *Params);
TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc(
const TemplateArgumentLoc &TALoc);
bool ImportTemplateArguments(const TemplateArgument *FromArgs,
unsigned NumFromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs);
+ SmallVectorImpl<TemplateArgument> &ToArgs);
+
template <typename InContainerTy>
bool ImportTemplateArgumentListInfo(const InContainerTy &Container,
TemplateArgumentListInfo &ToTAInfo);
+
+ template<typename InContainerTy>
+ bool ImportTemplateArgumentListInfo(SourceLocation FromLAngleLoc,
+ SourceLocation FromRAngleLoc,
+ const InContainerTy &Container,
+ TemplateArgumentListInfo &Result);
+
+ using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
+ using OptionalTemplateArgsTy = Optional<TemplateArgsTy>;
+ std::tuple<FunctionTemplateDecl *, OptionalTemplateArgsTy>
+ ImportFunctionTemplateWithTemplateArgsFromSpecialization(
+ FunctionDecl *FromFD);
+
+ bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+
+ bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
bool IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
@@ -145,6 +304,7 @@ namespace clang {
bool IsStructuralMatch(EnumConstantDecl *FromEC, EnumConstantDecl *ToEC);
bool IsStructuralMatch(FunctionTemplateDecl *From,
FunctionTemplateDecl *To);
+ bool IsStructuralMatch(FunctionDecl *From, FunctionDecl *To);
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
Decl *VisitDecl(Decl *D);
@@ -185,7 +345,6 @@ namespace clang {
Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
-
ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list);
Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
@@ -282,29 +441,38 @@ namespace clang {
Expr *VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE);
Expr *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
Expr *VisitPackExpansionExpr(PackExpansionExpr *E);
+ Expr *VisitSizeOfPackExpr(SizeOfPackExpr *E);
Expr *VisitCXXNewExpr(CXXNewExpr *CE);
Expr *VisitCXXDeleteExpr(CXXDeleteExpr *E);
Expr *VisitCXXConstructExpr(CXXConstructExpr *E);
Expr *VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
Expr *VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+ Expr *VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+ Expr *VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *CE);
+ Expr *VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
+ Expr *VisitUnresolvedMemberExpr(UnresolvedMemberExpr *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 *VisitLambdaExpr(LambdaExpr *LE);
Expr *VisitInitListExpr(InitListExpr *E);
+ Expr *VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
+ Expr *VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E);
Expr *VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
Expr *VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
Expr *VisitTypeTraitExpr(TypeTraitExpr *E);
-
+ Expr *VisitCXXTypeidExpr(CXXTypeidExpr *E);
template<typename IIter, typename OIter>
void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) {
- typedef typename std::remove_reference<decltype(*Obegin)>::type ItemT;
+ using ItemT = typename std::remove_reference<decltype(*Obegin)>::type;
+
ASTImporter &ImporterRef = Importer;
std::transform(Ibegin, Iend, Obegin,
[&ImporterRef](ItemT From) -> ItemT {
@@ -314,13 +482,13 @@ namespace clang {
template<typename IIter, typename OIter>
bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
- typedef typename std::remove_reference<decltype(**Obegin)>::type ItemT;
+ using ItemT = typename std::remove_reference<decltype(**Obegin)>::type;
+
ASTImporter &ImporterRef = Importer;
bool Failed = false;
std::transform(Ibegin, Iend, Obegin,
[&ImporterRef, &Failed](ItemT *From) -> ItemT * {
- ItemT *To = cast_or_null<ItemT>(
- ImporterRef.Import(From));
+ auto *To = cast_or_null<ItemT>(ImporterRef.Import(From));
if (!To && From)
Failed = true;
return To;
@@ -342,9 +510,58 @@ namespace clang {
// Importing overrides.
void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
+
+ FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
};
+
+template <typename InContainerTy>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+ SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
+ const InContainerTy &Container, TemplateArgumentListInfo &Result) {
+ TemplateArgumentListInfo ToTAInfo(Importer.Import(FromLAngleLoc),
+ Importer.Import(FromRAngleLoc));
+ if (ImportTemplateArgumentListInfo(Container, ToTAInfo))
+ return true;
+ Result = ToTAInfo;
+ return false;
+}
+
+template <>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>(
+ const TemplateArgumentListInfo &From, TemplateArgumentListInfo &Result) {
+ return ImportTemplateArgumentListInfo(
+ From.getLAngleLoc(), From.getRAngleLoc(), From.arguments(), Result);
+}
+
+template <>
+bool ASTNodeImporter::ImportTemplateArgumentListInfo<
+ ASTTemplateArgumentListInfo>(const ASTTemplateArgumentListInfo &From,
+ TemplateArgumentListInfo &Result) {
+ return ImportTemplateArgumentListInfo(From.LAngleLoc, From.RAngleLoc,
+ From.arguments(), Result);
+}
+
+std::tuple<FunctionTemplateDecl *, ASTNodeImporter::OptionalTemplateArgsTy>
+ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
+ FunctionDecl *FromFD) {
+ assert(FromFD->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization);
+ auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
+ auto *Template = cast_or_null<FunctionTemplateDecl>(
+ Importer.Import(FTSInfo->getTemplate()));
+
+ // Import template arguments.
+ auto TemplArgs = FTSInfo->TemplateArguments->asArray();
+ TemplateArgsTy ToTemplArgs;
+ if (ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
+ ToTemplArgs)) // Error during import.
+ return std::make_tuple(Template, OptionalTemplateArgsTy());
+
+ return std::make_tuple(Template, ToTemplArgs);
}
+} // namespace clang
+
//----------------------------------------------------------------------------
// Import Types
//----------------------------------------------------------------------------
@@ -354,13 +571,13 @@ using namespace clang;
QualType ASTNodeImporter::VisitType(const Type *T) {
Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
<< T->getTypeClassName();
- return QualType();
+ return {};
}
QualType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
QualType UnderlyingType = Importer.Import(T->getValueType());
if(UnderlyingType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getAtomicType(UnderlyingType);
}
@@ -413,7 +630,7 @@ QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
QualType OrigT = Importer.Import(T->getOriginalType());
if (OrigT.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getDecayedType(OrigT);
}
@@ -421,7 +638,7 @@ QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getComplexType(ToElementType);
}
@@ -429,7 +646,7 @@ QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
QualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
QualType ToPointeeType = Importer.Import(T->getPointeeType());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getPointerType(ToPointeeType);
}
@@ -438,7 +655,7 @@ QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
// FIXME: Check for blocks support in "to" context.
QualType ToPointeeType = Importer.Import(T->getPointeeType());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getBlockPointerType(ToPointeeType);
}
@@ -448,7 +665,7 @@ ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
// FIXME: Check for C++ support in "to" context.
QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getLValueReferenceType(ToPointeeType);
}
@@ -458,7 +675,7 @@ ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
// FIXME: Check for C++0x support in "to" context.
QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getRValueReferenceType(ToPointeeType);
}
@@ -467,7 +684,7 @@ QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
// FIXME: Check for C++ support in "to" context.
QualType ToPointeeType = Importer.Import(T->getPointeeType());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
return Importer.getToContext().getMemberPointerType(ToPointeeType,
@@ -477,7 +694,7 @@ QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getConstantArrayType(ToElementType,
T->getSize(),
@@ -489,7 +706,7 @@ QualType
ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getIncompleteArrayType(ToElementType,
T->getSizeModifier(),
@@ -499,11 +716,11 @@ ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
Expr *Size = Importer.Import(T->getSizeExpr());
if (!Size)
- return QualType();
+ return {};
SourceRange Brackets = Importer.Import(T->getBracketsRange());
return Importer.getToContext().getVariableArrayType(ToElementType, Size,
@@ -512,10 +729,28 @@ QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
Brackets);
}
+QualType ASTNodeImporter::VisitDependentSizedArrayType(
+ const DependentSizedArrayType *T) {
+ QualType ToElementType = Importer.Import(T->getElementType());
+ if (ToElementType.isNull())
+ return {};
+
+ // SizeExpr may be null if size is not specified directly.
+ // For example, 'int a[]'.
+ Expr *Size = Importer.Import(T->getSizeExpr());
+ if (!Size && T->getSizeExpr())
+ return {};
+
+ SourceRange Brackets = Importer.Import(T->getBracketsRange());
+ return Importer.getToContext().getDependentSizedArrayType(
+ ToElementType, Size, T->getSizeModifier(), T->getIndexTypeCVRQualifiers(),
+ Brackets);
+}
+
QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getVectorType(ToElementType,
T->getNumElements(),
@@ -525,7 +760,7 @@ QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
QualType ToElementType = Importer.Import(T->getElementType());
if (ToElementType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getExtVectorType(ToElementType,
T->getNumElements());
@@ -537,7 +772,7 @@ ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
// into C++? Should we make it variadic?
QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getFunctionNoProtoType(ToResultType,
T->getExtInfo());
@@ -546,14 +781,14 @@ ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
- return QualType();
+ return {};
// Import argument types
SmallVector<QualType, 4> ArgTypes;
for (const auto &A : T->param_types()) {
QualType ArgType = Importer.Import(A);
if (ArgType.isNull())
- return QualType();
+ return {};
ArgTypes.push_back(ArgType);
}
@@ -562,7 +797,7 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
for (const auto &E : T->exceptions()) {
QualType ExceptionType = Importer.Import(E);
if (ExceptionType.isNull())
- return QualType();
+ return {};
ExceptionTypes.push_back(ExceptionType);
}
@@ -588,16 +823,16 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
QualType ASTNodeImporter::VisitUnresolvedUsingType(
const UnresolvedUsingType *T) {
- UnresolvedUsingTypenameDecl *ToD = cast_or_null<UnresolvedUsingTypenameDecl>(
- Importer.Import(T->getDecl()));
+ const auto *ToD =
+ cast_or_null<UnresolvedUsingTypenameDecl>(Importer.Import(T->getDecl()));
if (!ToD)
- return QualType();
+ return {};
- UnresolvedUsingTypenameDecl *ToPrevD =
+ auto *ToPrevD =
cast_or_null<UnresolvedUsingTypenameDecl>(
Importer.Import(T->getDecl()->getPreviousDecl()));
if (!ToPrevD && T->getDecl()->getPreviousDecl())
- return QualType();
+ return {};
return Importer.getToContext().getTypeDeclType(ToD, ToPrevD);
}
@@ -605,16 +840,16 @@ QualType ASTNodeImporter::VisitUnresolvedUsingType(
QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
QualType ToInnerType = Importer.Import(T->getInnerType());
if (ToInnerType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getParenType(ToInnerType);
}
QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
- TypedefNameDecl *ToDecl
- = dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
+ auto *ToDecl =
+ dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
if (!ToDecl)
- return QualType();
+ return {};
return Importer.getToContext().getTypeDeclType(ToDecl);
}
@@ -622,7 +857,7 @@ QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
if (!ToExpr)
- return QualType();
+ return {};
return Importer.getToContext().getTypeOfExprType(ToExpr);
}
@@ -630,7 +865,7 @@ QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
if (ToUnderlyingType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getTypeOfType(ToUnderlyingType);
}
@@ -639,11 +874,11 @@ QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
// FIXME: Make sure that the "to" context supports C++0x!
Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
if (!ToExpr)
- return QualType();
+ return {};
QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
if (UnderlyingType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
}
@@ -652,7 +887,7 @@ QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
QualType ToBaseType = Importer.Import(T->getBaseType());
QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
if (ToBaseType.isNull() || ToUnderlyingType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getUnaryTransformType(ToBaseType,
ToUnderlyingType,
@@ -666,7 +901,7 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
if (!FromDeduced.isNull()) {
ToDeduced = Importer.Import(FromDeduced);
if (ToDeduced.isNull())
- return QualType();
+ return {};
}
return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(),
@@ -675,13 +910,13 @@ QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
QualType ASTNodeImporter::VisitInjectedClassNameType(
const InjectedClassNameType *T) {
- CXXRecordDecl *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl()));
+ auto *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl()));
if (!D)
- return QualType();
+ return {};
QualType InjType = Importer.Import(T->getInjectedSpecializationType());
if (InjType.isNull())
- return QualType();
+ return {};
// FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading
// See comments in InjectedClassNameType definition for details
@@ -696,19 +931,17 @@ QualType ASTNodeImporter::VisitInjectedClassNameType(
}
QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
- RecordDecl *ToDecl
- = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
+ auto *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
if (!ToDecl)
- return QualType();
+ return {};
return Importer.getToContext().getTagDeclType(ToDecl);
}
QualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
- EnumDecl *ToDecl
- = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
+ auto *ToDecl = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
if (!ToDecl)
- return QualType();
+ return {};
return Importer.getToContext().getTagDeclType(ToDecl);
}
@@ -722,25 +955,24 @@ QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
if (!FromModifiedType.isNull()) {
ToModifiedType = Importer.Import(FromModifiedType);
if (ToModifiedType.isNull())
- return QualType();
+ return {};
}
if (!FromEquivalentType.isNull()) {
ToEquivalentType = Importer.Import(FromEquivalentType);
if (ToEquivalentType.isNull())
- return QualType();
+ return {};
}
return Importer.getToContext().getAttributedType(T->getAttrKind(),
ToModifiedType, ToEquivalentType);
}
-
QualType ASTNodeImporter::VisitTemplateTypeParmType(
const TemplateTypeParmType *T) {
- TemplateTypeParmDecl *ParmDecl =
+ auto *ParmDecl =
cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl()));
if (!ParmDecl && T->getDecl())
- return QualType();
+ return {};
return Importer.getToContext().getTemplateTypeParmType(
T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl);
@@ -748,15 +980,15 @@ QualType ASTNodeImporter::VisitTemplateTypeParmType(
QualType ASTNodeImporter::VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *T) {
- const TemplateTypeParmType *Replaced =
+ const auto *Replaced =
cast_or_null<TemplateTypeParmType>(Importer.Import(
QualType(T->getReplacedParameter(), 0)).getTypePtr());
if (!Replaced)
- return QualType();
+ return {};
QualType Replacement = Importer.Import(T->getReplacementType());
if (Replacement.isNull())
- return QualType();
+ return {};
Replacement = Replacement.getCanonicalType();
return Importer.getToContext().getSubstTemplateTypeParmType(
@@ -767,11 +999,11 @@ QualType ASTNodeImporter::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
TemplateName ToTemplate = Importer.Import(T->getTemplateName());
if (ToTemplate.isNull())
- return QualType();
+ return {};
SmallVector<TemplateArgument, 2> ToTemplateArgs;
if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
- return QualType();
+ return {};
QualType ToCanonType;
if (!QualType(T, 0).isCanonical()) {
@@ -779,7 +1011,7 @@ QualType ASTNodeImporter::VisitTemplateSpecializationType(
= Importer.getFromContext().getCanonicalType(QualType(T, 0));
ToCanonType =Importer.Import(FromCanonType);
if (ToCanonType.isNull())
- return QualType();
+ return {};
}
return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
ToTemplateArgs,
@@ -792,31 +1024,75 @@ QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
if (T->getQualifier()) {
ToQualifier = Importer.Import(T->getQualifier());
if (!ToQualifier)
- return QualType();
+ return {};
}
QualType ToNamedType = Importer.Import(T->getNamedType());
if (ToNamedType.isNull())
- return QualType();
+ return {};
+
+ TagDecl *OwnedTagDecl =
+ cast_or_null<TagDecl>(Importer.Import(T->getOwnedTagDecl()));
+ if (!OwnedTagDecl && T->getOwnedTagDecl())
+ return {};
return Importer.getToContext().getElaboratedType(T->getKeyword(),
- ToQualifier, ToNamedType);
+ ToQualifier, ToNamedType,
+ OwnedTagDecl);
}
QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
QualType Pattern = Importer.Import(T->getPattern());
if (Pattern.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getPackExpansionType(Pattern,
T->getNumExpansions());
}
+QualType ASTNodeImporter::VisitDependentTemplateSpecializationType(
+ const DependentTemplateSpecializationType *T) {
+ NestedNameSpecifier *Qualifier = Importer.Import(T->getQualifier());
+ if (!Qualifier && T->getQualifier())
+ return {};
+
+ IdentifierInfo *Name = Importer.Import(T->getIdentifier());
+ if (!Name && T->getIdentifier())
+ return {};
+
+ SmallVector<TemplateArgument, 2> ToPack;
+ ToPack.reserve(T->getNumArgs());
+ if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToPack))
+ return {};
+
+ return Importer.getToContext().getDependentTemplateSpecializationType(
+ T->getKeyword(), Qualifier, Name, ToPack);
+}
+
+QualType ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
+ NestedNameSpecifier *NNS = Importer.Import(T->getQualifier());
+ if (!NNS && T->getQualifier())
+ return QualType();
+
+ IdentifierInfo *Name = Importer.Import(T->getIdentifier());
+ if (!Name && T->getIdentifier())
+ return QualType();
+
+ QualType Canon = (T == T->getCanonicalTypeInternal().getTypePtr())
+ ? QualType()
+ : Importer.Import(T->getCanonicalTypeInternal());
+ if (!Canon.isNull())
+ Canon = Canon.getCanonicalType();
+
+ return Importer.getToContext().getDependentNameType(T->getKeyword(), NNS,
+ Name, Canon);
+}
+
QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- ObjCInterfaceDecl *Class
- = dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
+ auto *Class =
+ dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
if (!Class)
- return QualType();
+ return {};
return Importer.getToContext().getObjCInterfaceType(Class);
}
@@ -824,23 +1100,22 @@ QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
QualType ToBaseType = Importer.Import(T->getBaseType());
if (ToBaseType.isNull())
- return QualType();
+ return {};
SmallVector<QualType, 4> TypeArgs;
for (auto TypeArg : T->getTypeArgsAsWritten()) {
QualType ImportedTypeArg = Importer.Import(TypeArg);
if (ImportedTypeArg.isNull())
- return QualType();
+ return {};
TypeArgs.push_back(ImportedTypeArg);
}
SmallVector<ObjCProtocolDecl *, 4> Protocols;
for (auto *P : T->quals()) {
- ObjCProtocolDecl *Protocol
- = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
+ auto *Protocol = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
if (!Protocol)
- return QualType();
+ return {};
Protocols.push_back(Protocol);
}
@@ -853,7 +1128,7 @@ QualType
ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
QualType ToPointeeType = Importer.Import(T->getPointeeType());
if (ToPointeeType.isNull())
- return QualType();
+ return {};
return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
}
@@ -866,8 +1141,26 @@ bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
DeclarationName &Name,
NamedDecl *&ToD,
SourceLocation &Loc) {
+ // Check if RecordDecl is in FunctionDecl parameters to avoid infinite loop.
+ // example: int struct_in_proto(struct data_t{int a;int b;} *d);
+ DeclContext *OrigDC = D->getDeclContext();
+ FunctionDecl *FunDecl;
+ if (isa<RecordDecl>(D) && (FunDecl = dyn_cast<FunctionDecl>(OrigDC)) &&
+ FunDecl->hasBody()) {
+ SourceRange RecR = D->getSourceRange();
+ SourceRange BodyR = FunDecl->getBody()->getSourceRange();
+ // If RecordDecl is not in Body (it is a param), we bail out.
+ if (RecR.isValid() && BodyR.isValid() &&
+ (RecR.getBegin() < BodyR.getBegin() ||
+ BodyR.getEnd() < RecR.getEnd())) {
+ Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+ << D->getDeclKindName();
+ return true;
+ }
+ }
+
// Import the context of this declaration.
- DC = Importer.ImportContext(D->getDeclContext());
+ DC = Importer.ImportContext(OrigDC);
if (!DC)
return true;
@@ -899,8 +1192,8 @@ void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
return;
}
- if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
- if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
+ if (auto *FromRecord = dyn_cast<RecordDecl>(FromD)) {
+ if (auto *ToRecord = cast_or_null<RecordDecl>(ToD)) {
if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() && !ToRecord->getDefinition()) {
ImportDefinition(FromRecord, ToRecord);
}
@@ -908,8 +1201,8 @@ void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
return;
}
- if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
- if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) {
+ if (auto *FromEnum = dyn_cast<EnumDecl>(FromD)) {
+ if (auto *ToEnum = cast_or_null<EnumDecl>(ToD)) {
if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
ImportDefinition(FromEnum, ToEnum);
}
@@ -963,6 +1256,27 @@ void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
Importer.Import(From);
}
+void ASTNodeImporter::ImportImplicitMethods(
+ const CXXRecordDecl *From, CXXRecordDecl *To) {
+ assert(From->isCompleteDefinition() && To->getDefinition() == To &&
+ "Import implicit methods to or from non-definition");
+
+ for (CXXMethodDecl *FromM : From->methods())
+ if (FromM->isImplicit())
+ Importer.Import(FromM);
+}
+
+static void setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
+ ASTImporter &Importer) {
+ if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
+ auto *ToTypedef =
+ cast_or_null<TypedefNameDecl>(Importer.Import(FromTypedef));
+ assert (ToTypedef && "Failed to import typedef of an anonymous structure");
+
+ To->setTypedefNameForAnonDecl(ToTypedef);
+ }
+}
+
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ImportDefinitionKind Kind) {
if (To->getDefinition() || To->isBeingDefined()) {
@@ -973,10 +1287,12 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
}
To->startDefinition();
+
+ setTypedefNameForAnonDecl(From, To, Importer);
// Add base classes.
- if (CXXRecordDecl *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
- CXXRecordDecl *FromCXX = cast<CXXRecordDecl>(From);
+ if (auto *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
+ auto *FromCXX = cast<CXXRecordDecl>(From);
struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
@@ -988,7 +1304,10 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.Polymorphic = FromData.Polymorphic;
ToData.Abstract = FromData.Abstract;
ToData.IsStandardLayout = FromData.IsStandardLayout;
- ToData.HasNoNonEmptyBases = FromData.HasNoNonEmptyBases;
+ ToData.IsCXX11StandardLayout = FromData.IsCXX11StandardLayout;
+ ToData.HasBasesWithFields = FromData.HasBasesWithFields;
+ ToData.HasBasesWithNonStaticDataMembers =
+ FromData.HasBasesWithNonStaticDataMembers;
ToData.HasPrivateFields = FromData.HasPrivateFields;
ToData.HasProtectedFields = FromData.HasProtectedFields;
ToData.HasPublicFields = FromData.HasPublicFields;
@@ -1022,7 +1341,6 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
= FromData.HasConstexprNonCopyMoveConstructor;
ToData.HasDefaultedDefaultConstructor
= FromData.HasDefaultedDefaultConstructor;
- ToData.CanPassInRegisters = FromData.CanPassInRegisters;
ToData.DefaultedDefaultConstructorIsConstexpr
= FromData.DefaultedDefaultConstructorIsConstexpr;
ToData.HasConstexprDefaultConstructor
@@ -1043,7 +1361,6 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
= FromData.HasDeclaredCopyConstructorWithConstParam;
ToData.HasDeclaredCopyAssignmentWithConstParam
= FromData.HasDeclaredCopyAssignmentWithConstParam;
- ToData.IsLambda = FromData.IsLambda;
SmallVector<CXXBaseSpecifier *, 4> Bases;
for (const auto &Base1 : FromCXX->bases()) {
@@ -1103,6 +1420,8 @@ bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
To->startDefinition();
+ setTypedefNameForAnonDecl(From, To, Importer);
+
QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
if (T.isNull())
return true;
@@ -1154,36 +1473,36 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
case TemplateArgument::Type: {
QualType ToType = Importer.Import(From.getAsType());
if (ToType.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(ToType);
}
case TemplateArgument::Integral: {
QualType ToType = Importer.Import(From.getIntegralType());
if (ToType.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(From, ToType);
}
case TemplateArgument::Declaration: {
- ValueDecl *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
+ auto *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
QualType ToType = Importer.Import(From.getParamTypeForDecl());
if (!To || ToType.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(To, ToType);
}
case TemplateArgument::NullPtr: {
QualType ToType = Importer.Import(From.getNullPtrType());
if (ToType.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(ToType, /*isNullPtr*/true);
}
case TemplateArgument::Template: {
TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
if (ToTemplate.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(ToTemplate);
}
@@ -1192,7 +1511,7 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
TemplateName ToTemplate
= Importer.Import(From.getAsTemplateOrTemplatePattern());
if (ToTemplate.isNull())
- return TemplateArgument();
+ return {};
return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
}
@@ -1206,7 +1525,7 @@ ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
SmallVector<TemplateArgument, 2> ToPack;
ToPack.reserve(From.pack_size());
if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
- return TemplateArgument();
+ return {};
return TemplateArgument(
llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
@@ -1254,6 +1573,9 @@ bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
return false;
}
+// We cannot use Optional<> pattern here and below because
+// TemplateArgumentListInfo's operator new is declared as deleted so it cannot
+// be stored in Optional.
template <typename InContainerTy>
bool ASTNodeImporter::ImportTemplateArgumentListInfo(
const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
@@ -1266,13 +1588,27 @@ bool ASTNodeImporter::ImportTemplateArgumentListInfo(
return false;
}
-bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
+static StructuralEquivalenceKind
+getStructuralEquivalenceKind(const ASTImporter &Importer) {
+ return Importer.isMinimalImport() ? StructuralEquivalenceKind::Minimal
+ : StructuralEquivalenceKind::Default;
+}
+
+bool ASTNodeImporter::IsStructuralMatch(Decl *From, Decl *To, bool Complain) {
+ StructuralEquivalenceContext Ctx(
+ Importer.getFromContext(), Importer.getToContext(),
+ Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+ false, Complain);
+ return Ctx.IsEquivalent(From, To);
+}
+
+bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
RecordDecl *ToRecord, bool Complain) {
// Eliminate a potential failure point where we attempt to re-import
// something we're trying to import while completing ToRecord.
Decl *ToOrigin = Importer.GetOriginalDecl(ToRecord);
if (ToOrigin) {
- RecordDecl *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin);
+ auto *ToOriginRecord = dyn_cast<RecordDecl>(ToOrigin);
if (ToOriginRecord)
ToRecord = ToOriginRecord;
}
@@ -1280,36 +1616,46 @@ bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
StructuralEquivalenceContext Ctx(Importer.getFromContext(),
ToRecord->getASTContext(),
Importer.getNonEquivalentDecls(),
+ getStructuralEquivalenceKind(Importer),
false, Complain);
- return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
+ return Ctx.IsEquivalent(FromRecord, ToRecord);
}
bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
bool Complain) {
StructuralEquivalenceContext Ctx(
Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), false, Complain);
- return Ctx.IsStructurallyEquivalent(FromVar, ToVar);
+ Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+ false, Complain);
+ return Ctx.IsEquivalent(FromVar, ToVar);
}
bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
- StructuralEquivalenceContext Ctx(Importer.getFromContext(),
- Importer.getToContext(),
- Importer.getNonEquivalentDecls());
- return Ctx.IsStructurallyEquivalent(FromEnum, ToEnum);
+ StructuralEquivalenceContext Ctx(
+ Importer.getFromContext(), Importer.getToContext(),
+ Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer));
+ return Ctx.IsEquivalent(FromEnum, ToEnum);
}
bool ASTNodeImporter::IsStructuralMatch(FunctionTemplateDecl *From,
FunctionTemplateDecl *To) {
StructuralEquivalenceContext Ctx(
Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), false, false);
- return Ctx.IsStructurallyEquivalent(From, To);
+ Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+ false, false);
+ return Ctx.IsEquivalent(From, To);
+}
+
+bool ASTNodeImporter::IsStructuralMatch(FunctionDecl *From, FunctionDecl *To) {
+ StructuralEquivalenceContext Ctx(
+ Importer.getFromContext(), Importer.getToContext(),
+ Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer),
+ false, false);
+ return Ctx.IsEquivalent(From, To);
}
bool ASTNodeImporter::IsStructuralMatch(EnumConstantDecl *FromEC,
- EnumConstantDecl *ToEC)
-{
+ EnumConstantDecl *ToEC) {
const llvm::APSInt &FromVal = FromEC->getInitVal();
const llvm::APSInt &ToVal = ToEC->getInitVal();
@@ -1322,16 +1668,18 @@ bool ASTNodeImporter::IsStructuralMatch(ClassTemplateDecl *From,
ClassTemplateDecl *To) {
StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Importer.getToContext(),
- Importer.getNonEquivalentDecls());
- return Ctx.IsStructurallyEquivalent(From, To);
+ Importer.getNonEquivalentDecls(),
+ getStructuralEquivalenceKind(Importer));
+ return Ctx.IsEquivalent(From, To);
}
bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
VarTemplateDecl *To) {
StructuralEquivalenceContext Ctx(Importer.getFromContext(),
Importer.getToContext(),
- Importer.getNonEquivalentDecls());
- return Ctx.IsStructurallyEquivalent(From, To);
+ Importer.getNonEquivalentDecls(),
+ getStructuralEquivalenceKind(Importer));
+ return Ctx.IsEquivalent(From, To);
}
Decl *ASTNodeImporter::VisitDecl(Decl *D) {
@@ -1356,9 +1704,11 @@ Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
- EmptyDecl *ToD = EmptyDecl::Create(Importer.getToContext(), DC, Loc);
+ EmptyDecl *ToD;
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc))
+ return ToD;
+
ToD->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToD);
LexicalDC->addDeclInternal(ToD);
return ToD;
}
@@ -1367,13 +1717,12 @@ Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
TranslationUnitDecl *ToD =
Importer.getToContext().getTranslationUnitDecl();
- Importer.Imported(D, ToD);
+ Importer.MapImported(D, ToD);
return ToD;
}
Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
-
SourceLocation Loc = Importer.Import(D->getLocation());
SourceLocation ColonLoc = Importer.Import(D->getColonLoc());
@@ -1382,19 +1731,17 @@ Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
if (!DC)
return nullptr;
- AccessSpecDecl *accessSpecDecl
- = AccessSpecDecl::Create(Importer.getToContext(), D->getAccess(),
- DC, Loc, ColonLoc);
-
- if (!accessSpecDecl)
- return nullptr;
+ AccessSpecDecl *ToD;
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), D->getAccess(),
+ DC, Loc, ColonLoc))
+ return ToD;
// Lexical DeclContext and Semantic DeclContext
// is always the same for the accessSpec.
- accessSpecDecl->setLexicalDeclContext(DC);
- DC->addDeclInternal(accessSpecDecl);
+ ToD->setLexicalDeclContext(DC);
+ DC->addDeclInternal(ToD);
- return accessSpecDecl;
+ return ToD;
}
Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
@@ -1412,17 +1759,18 @@ Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
return nullptr;
StringLiteral *FromMsg = D->getMessage();
- StringLiteral *ToMsg = cast_or_null<StringLiteral>(Importer.Import(FromMsg));
+ auto *ToMsg = cast_or_null<StringLiteral>(Importer.Import(FromMsg));
if (!ToMsg && FromMsg)
return nullptr;
- StaticAssertDecl *ToD = StaticAssertDecl::Create(
- Importer.getToContext(), DC, Loc, AssertExpr, ToMsg,
- Importer.Import(D->getRParenLoc()), D->isFailed());
+ StaticAssertDecl *ToD;
+ if (GetImportedOrCreateDecl(
+ ToD, D, Importer.getToContext(), DC, Loc, AssertExpr, ToMsg,
+ Importer.Import(D->getRParenLoc()), D->isFailed()))
+ return ToD;
ToD->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToD);
- Importer.Imported(D, ToD);
return ToD;
}
@@ -1442,7 +1790,7 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
// This is an anonymous namespace. Adopt an existing anonymous
// namespace if we can.
// FIXME: Not testable.
- if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
+ if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
MergeWithNamespace = TU->getAnonymousNamespace();
else
MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
@@ -1450,17 +1798,17 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Namespace))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Namespace))
continue;
- if (NamespaceDecl *FoundNS = dyn_cast<NamespaceDecl>(FoundDecls[I])) {
+ if (auto *FoundNS = dyn_cast<NamespaceDecl>(FoundDecl)) {
MergeWithNamespace = FoundNS;
ConflictingDecls.clear();
break;
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -1473,24 +1821,24 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
// Create the "to" namespace, if needed.
NamespaceDecl *ToNamespace = MergeWithNamespace;
if (!ToNamespace) {
- ToNamespace = NamespaceDecl::Create(Importer.getToContext(), DC,
- D->isInline(),
- Importer.Import(D->getLocStart()),
- Loc, Name.getAsIdentifierInfo(),
- /*PrevDecl=*/nullptr);
+ if (GetImportedOrCreateDecl(
+ ToNamespace, D, Importer.getToContext(), DC, D->isInline(),
+ Importer.Import(D->getLocStart()), Loc, Name.getAsIdentifierInfo(),
+ /*PrevDecl=*/nullptr))
+ return ToNamespace;
ToNamespace->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToNamespace);
// If this is an anonymous namespace, register it as the anonymous
// namespace within its context.
if (!Name) {
- if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(DC))
+ if (auto *TU = dyn_cast<TranslationUnitDecl>(DC))
TU->setAnonymousNamespace(ToNamespace);
else
cast<NamespaceDecl>(DC)->setAnonymousNamespace(ToNamespace);
}
}
- Importer.Imported(D, ToNamespace);
+ Importer.MapImported(D, ToNamespace);
ImportDeclContext(D);
@@ -1510,8 +1858,8 @@ Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
// NOTE: No conflict resolution is done for namespace aliases now.
- NamespaceDecl *TargetDecl = cast_or_null<NamespaceDecl>(
- Importer.Import(D->getNamespace()));
+ auto *TargetDecl = cast_or_null<NamespaceDecl>(
+ Importer.Import(D->getNamespace()));
if (!TargetDecl)
return nullptr;
@@ -1523,13 +1871,15 @@ Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
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);
+ NamespaceAliasDecl *ToD;
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC,
+ Importer.Import(D->getNamespaceLoc()),
+ Importer.Import(D->getAliasLoc()), ToII, ToQLoc,
+ Importer.Import(D->getTargetNameLoc()),
+ TargetDecl))
+ return ToD;
ToD->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToD);
LexicalDC->addDeclInternal(ToD);
return ToD;
@@ -1554,17 +1904,16 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
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))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (TypedefNameDecl *FoundTypedef =
- dyn_cast<TypedefNameDecl>(FoundDecls[I])) {
+ if (auto *FoundTypedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
FoundTypedef->getUnderlyingType()))
- return Importer.Imported(D, FoundTypedef);
+ return Importer.MapImported(D, FoundTypedef);
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -1584,22 +1933,25 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
// Create the new typedef node.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
SourceLocation StartL = Importer.Import(D->getLocStart());
+
TypedefNameDecl *ToTypedef;
- if (IsAlias)
- ToTypedef = TypeAliasDecl::Create(Importer.getToContext(), DC,
- StartL, Loc,
- Name.getAsIdentifierInfo(),
- TInfo);
- else
- ToTypedef = TypedefDecl::Create(Importer.getToContext(), DC,
- StartL, Loc,
- Name.getAsIdentifierInfo(),
- TInfo);
+ if (IsAlias) {
+ if (GetImportedOrCreateDecl<TypeAliasDecl>(
+ ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
+ Name.getAsIdentifierInfo(), TInfo))
+ return ToTypedef;
+ } else if (GetImportedOrCreateDecl<TypedefDecl>(
+ ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
+ Name.getAsIdentifierInfo(), TInfo))
+ return ToTypedef;
ToTypedef->setAccess(D->getAccess());
ToTypedef->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToTypedef);
- LexicalDC->addDeclInternal(ToTypedef);
+
+ // Templated declarations should not appear in DeclContext.
+ TypeAliasDecl *FromAlias = IsAlias ? cast<TypeAliasDecl>(D) : nullptr;
+ if (!FromAlias || !FromAlias->getDescribedAliasTemplate())
+ LexicalDC->addDeclInternal(ToTypedef);
return ToTypedef;
}
@@ -1617,11 +1969,11 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
- NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ NamedDecl *FoundD;
+ if (ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
return nullptr;
- if (ToD)
- return ToD;
+ if (FoundD)
+ return FoundD;
// 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
@@ -1631,13 +1983,12 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
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))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundAlias =
- dyn_cast<TypeAliasTemplateDecl>(FoundDecls[I]))
- return Importer.Imported(D, FoundAlias);
- ConflictingDecls.push_back(FoundDecls[I]);
+ if (auto *FoundAlias = dyn_cast<TypeAliasTemplateDecl>(FoundDecl))
+ return Importer.MapImported(D, FoundAlias);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -1654,19 +2005,22 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
if (!Params)
return nullptr;
- NamedDecl *TemplDecl = cast_or_null<NamedDecl>(
+ auto *TemplDecl = cast_or_null<TypeAliasDecl>(
Importer.Import(D->getTemplatedDecl()));
if (!TemplDecl)
return nullptr;
- TypeAliasTemplateDecl *ToAlias = TypeAliasTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, Params, TemplDecl);
+ TypeAliasTemplateDecl *ToAlias;
+ if (GetImportedOrCreateDecl(ToAlias, D, Importer.getToContext(), DC, Loc,
+ Name, Params, TemplDecl))
+ return ToAlias;
+
+ TemplDecl->setDescribedAliasTemplate(ToAlias);
ToAlias->setAccess(D->getAccess());
ToAlias->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToAlias);
LexicalDC->addDeclInternal(ToAlias);
- return ToD;
+ return ToAlias;
}
Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
@@ -1682,17 +2036,18 @@ Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
assert(LexicalDC->isFunctionOrMethod());
- LabelDecl *ToLabel = D->isGnuLocal()
- ? LabelDecl::Create(Importer.getToContext(),
- DC, Importer.Import(D->getLocation()),
- Name.getAsIdentifierInfo(),
- Importer.Import(D->getLocStart()))
- : LabelDecl::Create(Importer.getToContext(),
- DC, Importer.Import(D->getLocation()),
- Name.getAsIdentifierInfo());
- Importer.Imported(D, ToLabel);
-
- LabelStmt *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt()));
+ LabelDecl *ToLabel;
+ if (D->isGnuLocal()
+ ? GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC,
+ Importer.Import(D->getLocation()),
+ Name.getAsIdentifierInfo(),
+ Importer.Import(D->getLocStart()))
+ : GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC,
+ Importer.Import(D->getLocation()),
+ Name.getAsIdentifierInfo()))
+ return ToLabel;
+
+ auto *Label = cast_or_null<LabelStmt>(Importer.Import(D->getStmt()));
if (!Label)
return nullptr;
@@ -1727,22 +2082,22 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- Decl *Found = FoundDecls[I];
- if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
- if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
+ Decl *Found = FoundDecl;
+ if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
+ if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
Found = Tag->getDecl();
}
- if (EnumDecl *FoundEnum = dyn_cast<EnumDecl>(Found)) {
+ if (auto *FoundEnum = dyn_cast<EnumDecl>(Found)) {
if (IsStructuralMatch(D, FoundEnum))
- return Importer.Imported(D, FoundEnum);
+ return Importer.MapImported(D, FoundEnum);
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -1751,18 +2106,19 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
ConflictingDecls.size());
}
}
-
+
// Create the enum declaration.
- EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getLocStart()),
- Loc, Name.getAsIdentifierInfo(), nullptr,
- D->isScoped(), D->isScopedUsingClassTag(),
- D->isFixed());
+ EnumDecl *D2;
+ if (GetImportedOrCreateDecl(
+ D2, D, Importer.getToContext(), DC, Importer.Import(D->getLocStart()),
+ Loc, Name.getAsIdentifierInfo(), nullptr, D->isScoped(),
+ D->isScopedUsingClassTag(), D->isFixed()))
+ return D2;
+
// Import the qualifier, if any.
D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
D2->setAccess(D->getAccess());
D2->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, D2);
LexicalDC->addDeclInternal(D2);
// Import the integer type.
@@ -1783,14 +2139,20 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
// but this particular declaration is not that definition, import the
// definition and map to that.
TagDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
+ if (Definition && Definition != D &&
+ // In contrast to a normal CXXRecordDecl, the implicit
+ // CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
+ // The definition of the implicit CXXRecordDecl in this case is the
+ // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
+ // condition in order to be able to import the implict Decl.
+ !D->isImplicit()) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
-
+
// Import the major distinguishing characteristics of this record.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -1824,30 +2186,27 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
D->getASTContext().getExternalSource()->CompleteType(D);
}
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- Decl *Found = FoundDecls[I];
- if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
- if (const TagType *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
+ Decl *Found = FoundDecl;
+ if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
+ if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
Found = Tag->getDecl();
}
-
- if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
- if (D->isAnonymousStructOrUnion() &&
- FoundRecord->isAnonymousStructOrUnion()) {
- // If both anonymous structs/unions are in a record context, make sure
- // they occur in the same location in the context records.
- if (Optional<unsigned> Index1 =
- StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
- D)) {
- if (Optional<unsigned> Index2 = StructuralEquivalenceContext::
- findUntaggedStructOrUnionIndex(FoundRecord)) {
- if (*Index1 != *Index2)
- continue;
- }
- }
+
+ if (D->getDescribedTemplate()) {
+ if (auto *Template = dyn_cast<ClassTemplateDecl>(Found))
+ Found = Template->getTemplatedDecl();
+ else
+ continue;
+ }
+
+ if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
+ if (!SearchName) {
+ if (!IsStructuralMatch(D, FoundRecord, false))
+ continue;
}
PrevDecl = FoundRecord;
@@ -1861,8 +2220,19 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
// The record types structurally match, or the "from" translation
// unit only had a forward declaration anyway; call it the same
// function.
- // FIXME: For C++, we should also merge methods here.
- return Importer.Imported(D, FoundDef);
+ // FIXME: Structural equivalence check should check for same
+ // user-defined methods.
+ Importer.MapImported(D, FoundDef);
+ if (const auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
+ auto *FoundCXX = dyn_cast<CXXRecordDecl>(FoundDef);
+ assert(FoundCXX && "Record type mismatch");
+
+ if (D->isCompleteDefinition() && !Importer.isMinimalImport())
+ // FoundDef may not have every implicit method that D has
+ // because implicit methods are created only if they are used.
+ ImportImplicitMethods(DCXX, FoundCXX);
+ }
+ return FoundDef;
}
} else if (!D->isCompleteDefinition()) {
// We have a forward declaration of this type, so adopt that forward
@@ -1889,7 +2259,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
}
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty() && SearchName) {
@@ -1904,53 +2274,80 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
SourceLocation StartLoc = Importer.Import(D->getLocStart());
if (!D2) {
CXXRecordDecl *D2CXX = nullptr;
- if (CXXRecordDecl *DCXX = llvm::dyn_cast<CXXRecordDecl>(D)) {
+ if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
if (DCXX->isLambda()) {
TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo());
- D2CXX = CXXRecordDecl::CreateLambda(Importer.getToContext(),
- DC, TInfo, Loc,
- DCXX->isDependentLambda(),
- DCXX->isGenericLambda(),
- DCXX->getLambdaCaptureDefault());
+ if (GetImportedOrCreateSpecialDecl(
+ D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
+ DC, TInfo, Loc, DCXX->isDependentLambda(),
+ DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
+ return D2CXX;
Decl *CDecl = Importer.Import(DCXX->getLambdaContextDecl());
if (DCXX->getLambdaContextDecl() && !CDecl)
return nullptr;
D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), CDecl);
- } else if (DCXX->isInjectedClassName()) {
- // We have to be careful to do a similar dance to the one in
- // Sema::ActOnStartCXXMemberDeclarations
- CXXRecordDecl *const PrevDecl = nullptr;
- const bool DelayTypeCreation = true;
- D2CXX = CXXRecordDecl::Create(
- Importer.getToContext(), D->getTagKind(), DC, StartLoc, Loc,
- Name.getAsIdentifierInfo(), PrevDecl, DelayTypeCreation);
- Importer.getToContext().getTypeDeclType(
- D2CXX, llvm::dyn_cast<CXXRecordDecl>(DC));
+ } else if (DCXX->isInjectedClassName()) {
+ // We have to be careful to do a similar dance to the one in
+ // Sema::ActOnStartCXXMemberDeclarations
+ CXXRecordDecl *const PrevDecl = nullptr;
+ const bool DelayTypeCreation = true;
+ if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
+ D->getTagKind(), DC, StartLoc, Loc,
+ Name.getAsIdentifierInfo(), PrevDecl,
+ DelayTypeCreation))
+ return D2CXX;
+ Importer.getToContext().getTypeDeclType(
+ D2CXX, dyn_cast<CXXRecordDecl>(DC));
} else {
- D2CXX = CXXRecordDecl::Create(Importer.getToContext(),
- D->getTagKind(),
- DC, StartLoc, Loc,
- Name.getAsIdentifierInfo());
+ if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
+ D->getTagKind(), DC, StartLoc, Loc,
+ Name.getAsIdentifierInfo(),
+ cast_or_null<CXXRecordDecl>(PrevDecl)))
+ return D2CXX;
}
+
D2 = D2CXX;
D2->setAccess(D->getAccess());
-
- Importer.Imported(D, D2);
+ D2->setLexicalDeclContext(LexicalDC);
+ if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
+ LexicalDC->addDeclInternal(D2);
if (ClassTemplateDecl *FromDescribed =
DCXX->getDescribedClassTemplate()) {
- ClassTemplateDecl *ToDescribed = cast_or_null<ClassTemplateDecl>(
- Importer.Import(FromDescribed));
+ auto *ToDescribed = cast_or_null<ClassTemplateDecl>(
+ Importer.Import(FromDescribed));
if (!ToDescribed)
return nullptr;
D2CXX->setDescribedClassTemplate(ToDescribed);
-
+ if (!DCXX->isInjectedClassName()) {
+ // In a record describing a template the type should be an
+ // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
+ // previously set type to the correct value here (ToDescribed is not
+ // available at record create).
+ // FIXME: The previous type is cleared but not removed from
+ // ASTContext's internal storage.
+ CXXRecordDecl *Injected = nullptr;
+ for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
+ auto *Record = dyn_cast<CXXRecordDecl>(Found);
+ if (Record && Record->isInjectedClassName()) {
+ Injected = Record;
+ break;
+ }
+ }
+ D2CXX->setTypeForDecl(nullptr);
+ Importer.getToContext().getInjectedClassNameType(D2CXX,
+ ToDescribed->getInjectedClassNameSpecialization());
+ if (Injected) {
+ Injected->setTypeForDecl(nullptr);
+ Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+ }
+ }
} else if (MemberSpecializationInfo *MemberInfo =
DCXX->getMemberSpecializationInfo()) {
TemplateSpecializationKind SK =
MemberInfo->getTemplateSpecializationKind();
CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass();
- CXXRecordDecl *ToInst =
+ auto *ToInst =
cast_or_null<CXXRecordDecl>(Importer.Import(FromInst));
if (FromInst && !ToInst)
return nullptr;
@@ -1958,24 +2355,21 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
Importer.Import(MemberInfo->getPointOfInstantiation()));
}
-
} else {
- D2 = RecordDecl::Create(Importer.getToContext(), D->getTagKind(),
- DC, StartLoc, Loc, Name.getAsIdentifierInfo());
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
+ D->getTagKind(), DC, StartLoc, Loc,
+ Name.getAsIdentifierInfo(), PrevDecl))
+ return D2;
+ D2->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(D2);
}
-
+
D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
if (D->isAnonymousStructOrUnion())
D2->setAnonymousStructOrUnion(true);
- if (PrevDecl) {
- // FIXME: do this for all Redeclarables, not just RecordDecls.
- D2->setPreviousDecl(PrevDecl);
- }
}
-
- Importer.Imported(D, D2);
+
+ Importer.MapImported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
return nullptr;
@@ -2005,17 +2399,16 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
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))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (EnumConstantDecl *FoundEnumConstant
- = dyn_cast<EnumConstantDecl>(FoundDecls[I])) {
+ if (auto *FoundEnumConstant = dyn_cast<EnumConstantDecl>(FoundDecl)) {
if (IsStructuralMatch(D, FoundEnumConstant))
- return Importer.Imported(D, FoundEnumConstant);
+ return Importer.MapImported(D, FoundEnumConstant);
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -2031,18 +2424,120 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
if (D->getInitExpr() && !Init)
return nullptr;
- EnumConstantDecl *ToEnumerator
- = EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
- Name.getAsIdentifierInfo(), T,
- Init, D->getInitVal());
+ EnumConstantDecl *ToEnumerator;
+ if (GetImportedOrCreateDecl(
+ ToEnumerator, D, Importer.getToContext(), cast<EnumDecl>(DC), Loc,
+ Name.getAsIdentifierInfo(), T, Init, D->getInitVal()))
+ return ToEnumerator;
+
ToEnumerator->setAccess(D->getAccess());
ToEnumerator->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToEnumerator);
LexicalDC->addDeclInternal(ToEnumerator);
return ToEnumerator;
}
+bool ASTNodeImporter::ImportTemplateInformation(FunctionDecl *FromFD,
+ FunctionDecl *ToFD) {
+ switch (FromFD->getTemplatedKind()) {
+ case FunctionDecl::TK_NonTemplate:
+ case FunctionDecl::TK_FunctionTemplate:
+ return false;
+
+ case FunctionDecl::TK_MemberSpecialization: {
+ auto *InstFD = cast_or_null<FunctionDecl>(
+ Importer.Import(FromFD->getInstantiatedFromMemberFunction()));
+ if (!InstFD)
+ return true;
+
+ TemplateSpecializationKind TSK = FromFD->getTemplateSpecializationKind();
+ SourceLocation POI = Importer.Import(
+ FromFD->getMemberSpecializationInfo()->getPointOfInstantiation());
+ ToFD->setInstantiationOfMemberFunction(InstFD, TSK);
+ ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(POI);
+ return false;
+ }
+
+ case FunctionDecl::TK_FunctionTemplateSpecialization: {
+ FunctionTemplateDecl* Template;
+ OptionalTemplateArgsTy ToTemplArgs;
+ std::tie(Template, ToTemplArgs) =
+ ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
+ if (!Template || !ToTemplArgs)
+ return true;
+
+ TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
+ Importer.getToContext(), *ToTemplArgs);
+
+ auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
+ TemplateArgumentListInfo ToTAInfo;
+ const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
+ if (FromTAArgsAsWritten)
+ if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ToTAInfo))
+ return true;
+
+ SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation());
+
+ TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
+ ToFD->setFunctionTemplateSpecialization(
+ Template, ToTAList, /* InsertPos= */ nullptr,
+ TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI);
+ return false;
+ }
+
+ case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
+ auto *FromInfo = FromFD->getDependentSpecializationInfo();
+ UnresolvedSet<8> TemplDecls;
+ unsigned NumTemplates = FromInfo->getNumTemplates();
+ for (unsigned I = 0; I < NumTemplates; I++) {
+ if (auto *ToFTD = cast_or_null<FunctionTemplateDecl>(
+ Importer.Import(FromInfo->getTemplate(I))))
+ TemplDecls.addDecl(ToFTD);
+ else
+ return true;
+ }
+
+ // Import TemplateArgumentListInfo.
+ TemplateArgumentListInfo ToTAInfo;
+ if (ImportTemplateArgumentListInfo(
+ FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
+ llvm::makeArrayRef(FromInfo->getTemplateArgs(),
+ FromInfo->getNumTemplateArgs()),
+ ToTAInfo))
+ return true;
+
+ ToFD->setDependentTemplateSpecialization(Importer.getToContext(),
+ TemplDecls, ToTAInfo);
+ return false;
+ }
+ }
+ llvm_unreachable("All cases should be covered!");
+}
+
+FunctionDecl *
+ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
+ FunctionTemplateDecl* Template;
+ OptionalTemplateArgsTy ToTemplArgs;
+ std::tie(Template, ToTemplArgs) =
+ ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
+ if (!Template || !ToTemplArgs)
+ return nullptr;
+
+ void *InsertPos = nullptr;
+ auto *FoundSpec = Template->findSpecialization(*ToTemplArgs, InsertPos);
+ return FoundSpec;
+}
+
Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
+
+ SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(D);
+ auto RedeclIt = Redecls.begin();
+ // Import the first part of the decl chain. I.e. import all previous
+ // declarations starting from the canonical decl.
+ for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt)
+ if (!Importer.Import(*RedeclIt))
+ return nullptr;
+ assert(*RedeclIt == D);
+
// Import the major distinguishing characteristics of this function.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -2053,33 +2548,54 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (ToD)
return ToD;
- const FunctionDecl *FoundWithoutBody = nullptr;
-
+ const FunctionDecl *FoundByLookup = nullptr;
+ FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
+
+ // If this is a function template specialization, then try to find the same
+ // existing specialization in the "to" context. The localUncachedLookup
+ // below will not find any specialization, but would find the primary
+ // template; thus, we have to skip normal lookup in case of specializations.
+ // FIXME handle member function templates (TK_MemberSpecialization) similarly?
+ if (D->getTemplatedKind() ==
+ FunctionDecl::TK_FunctionTemplateSpecialization) {
+ if (FunctionDecl *FoundFunction = FindFunctionTemplateSpecialization(D)) {
+ if (D->doesThisDeclarationHaveABody() &&
+ FoundFunction->hasBody())
+ return Importer.Imported(D, FoundFunction);
+ FoundByLookup = FoundFunction;
+ }
+ }
// 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()) {
+ else if (!LexicalDC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- unsigned IDNS = Decl::IDNS_Ordinary;
+ unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
+ // If template was found, look at the templated function.
+ if (FromFT) {
+ if (auto *Template = dyn_cast<FunctionTemplateDecl>(FoundDecl))
+ FoundDecl = Template->getTemplatedDecl();
+ else
+ continue;
+ }
+
+ if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) {
if (FoundFunction->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
- 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;
+ if (IsStructuralMatch(D, FoundFunction)) {
+ const FunctionDecl *Definition = nullptr;
+ if (D->doesThisDeclarationHaveABody() &&
+ FoundFunction->hasBody(Definition)) {
+ return Importer.MapImported(
+ D, const_cast<FunctionDecl *>(Definition));
}
- return Importer.Imported(D, FoundFunction);
+ FoundByLookup = FoundFunction;
+ break;
}
// FIXME: Check for overloading more carefully, e.g., by boosting
@@ -2098,7 +2614,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -2117,8 +2633,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
QualType FromTy = D->getType();
bool usedDifferentExceptionSpec = false;
- if (const FunctionProtoType *
- FromFPT = D->getType()->getAs<FunctionProtoType>()) {
+ if (const auto *FromFPT = D->getType()->getAs<FunctionProtoType>()) {
FunctionProtoType::ExtProtoInfo FromEPI = FromFPT->getExtProtoInfo();
// FunctionProtoType::ExtProtoInfo's ExceptionSpecDecl can point to the
// FunctionDecl that we are importing the FunctionProtoType for.
@@ -2142,75 +2657,66 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Import the function parameters.
SmallVector<ParmVarDecl *, 8> Parameters;
for (auto P : D->parameters()) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
+ auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
if (!ToP)
return nullptr;
Parameters.push_back(ToP);
}
- // Create the imported function.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+ if (D->getTypeSourceInfo() && !TInfo)
+ return nullptr;
+
+ // Create the imported function.
FunctionDecl *ToFunction = nullptr;
SourceLocation InnerLocStart = Importer.Import(D->getInnerLocStart());
- if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
- ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
- cast<CXXRecordDecl>(DC),
- InnerLocStart,
- NameInfo, T, TInfo,
- FromConstructor->isExplicit(),
- D->isInlineSpecified(),
- D->isImplicit(),
- D->isConstexpr());
+ if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (GetImportedOrCreateDecl<CXXConstructorDecl>(
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ InnerLocStart, NameInfo, T, TInfo, FromConstructor->isExplicit(),
+ D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
+ return ToFunction;
if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
SmallVector<CXXCtorInitializer *, 4> CtorInitializers;
- for (CXXCtorInitializer *I : FromConstructor->inits()) {
- CXXCtorInitializer *ToI =
- cast_or_null<CXXCtorInitializer>(Importer.Import(I));
+ for (auto *I : FromConstructor->inits()) {
+ auto *ToI = cast_or_null<CXXCtorInitializer>(Importer.Import(I));
if (!ToI && I)
return nullptr;
CtorInitializers.push_back(ToI);
}
- CXXCtorInitializer **Memory =
+ auto **Memory =
new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
- CXXConstructorDecl *ToCtor = llvm::cast<CXXConstructorDecl>(ToFunction);
+ auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
ToCtor->setCtorInitializers(Memory);
ToCtor->setNumCtorInitializers(NumInitializers);
}
} else if (isa<CXXDestructorDecl>(D)) {
- ToFunction = CXXDestructorDecl::Create(Importer.getToContext(),
- cast<CXXRecordDecl>(DC),
- InnerLocStart,
- NameInfo, T, TInfo,
- D->isInlineSpecified(),
- D->isImplicit());
- } else if (CXXConversionDecl *FromConversion
- = dyn_cast<CXXConversionDecl>(D)) {
- ToFunction = CXXConversionDecl::Create(Importer.getToContext(),
- cast<CXXRecordDecl>(DC),
- InnerLocStart,
- NameInfo, T, TInfo,
- D->isInlineSpecified(),
- FromConversion->isExplicit(),
- D->isConstexpr(),
- Importer.Import(D->getLocEnd()));
- } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
- ToFunction = CXXMethodDecl::Create(Importer.getToContext(),
- cast<CXXRecordDecl>(DC),
- InnerLocStart,
- NameInfo, T, TInfo,
- Method->getStorageClass(),
- Method->isInlineSpecified(),
- D->isConstexpr(),
- Importer.Import(D->getLocEnd()));
+ if (GetImportedOrCreateDecl<CXXDestructorDecl>(
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ InnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
+ D->isImplicit()))
+ return ToFunction;
+ } else if (CXXConversionDecl *FromConversion =
+ dyn_cast<CXXConversionDecl>(D)) {
+ if (GetImportedOrCreateDecl<CXXConversionDecl>(
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ InnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
+ FromConversion->isExplicit(), D->isConstexpr(), SourceLocation()))
+ return ToFunction;
+ } else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
+ if (GetImportedOrCreateDecl<CXXMethodDecl>(
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ InnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
+ Method->isInlineSpecified(), D->isConstexpr(), SourceLocation()))
+ return ToFunction;
} else {
- ToFunction = FunctionDecl::Create(Importer.getToContext(), DC,
- InnerLocStart,
- NameInfo, T, TInfo, D->getStorageClass(),
- D->isInlineSpecified(),
- D->hasWrittenPrototype(),
- D->isConstexpr());
+ if (GetImportedOrCreateDecl(ToFunction, D, Importer.getToContext(), DC,
+ InnerLocStart, NameInfo, T, TInfo,
+ D->getStorageClass(), D->isInlineSpecified(),
+ D->hasWrittenPrototype(), D->isConstexpr()))
+ return ToFunction;
}
// Import the qualifier, if any.
@@ -2220,21 +2726,31 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
ToFunction->setTrivial(D->isTrivial());
ToFunction->setPure(D->isPure());
- Importer.Imported(D, ToFunction);
+ ToFunction->setRangeEnd(Importer.Import(D->getLocEnd()));
// Set the parameters.
- for (unsigned I = 0, N = Parameters.size(); I != N; ++I) {
- Parameters[I]->setOwningFunction(ToFunction);
- ToFunction->addDeclInternal(Parameters[I]);
+ for (auto *Param : Parameters) {
+ Param->setOwningFunction(ToFunction);
+ ToFunction->addDeclInternal(Param);
}
ToFunction->setParams(Parameters);
- if (FoundWithoutBody) {
+ if (FoundByLookup) {
auto *Recent = const_cast<FunctionDecl *>(
- FoundWithoutBody->getMostRecentDecl());
+ FoundByLookup->getMostRecentDecl());
ToFunction->setPreviousDecl(Recent);
}
+ // We need to complete creation of FunctionProtoTypeLoc manually with setting
+ // params it refers to.
+ if (TInfo) {
+ if (auto ProtoLoc =
+ TInfo->getTypeLoc().IgnoreParens().getAs<FunctionProtoTypeLoc>()) {
+ for (unsigned I = 0, N = Parameters.size(); I != N; ++I)
+ ProtoLoc.setParam(I, Parameters[I]);
+ }
+ }
+
if (usedDifferentExceptionSpec) {
// Update FunctionProtoType::ExtProtoInfo.
QualType T = Importer.Import(D->getType());
@@ -2243,17 +2759,47 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ToFunction->setType(T);
}
- // Import the body, if any.
- if (Stmt *FromBody = D->getBody()) {
- if (Stmt *ToBody = Importer.Import(FromBody)) {
- ToFunction->setBody(ToBody);
+ // Import the describing template function, if any.
+ if (FromFT)
+ if (!Importer.Import(FromFT))
+ return nullptr;
+
+ if (D->doesThisDeclarationHaveABody()) {
+ if (Stmt *FromBody = D->getBody()) {
+ if (Stmt *ToBody = Importer.Import(FromBody)) {
+ ToFunction->setBody(ToBody);
+ }
}
}
// FIXME: Other bits to merge?
- // Add this function to the lexical context.
- LexicalDC->addDeclInternal(ToFunction);
+ // If it is a template, import all related things.
+ if (ImportTemplateInformation(D, ToFunction))
+ return nullptr;
+
+ bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
+
+ // TODO Can we generalize this approach to other AST nodes as well?
+ if (D->getDeclContext()->containsDeclAndLoad(D))
+ DC->addDeclInternal(ToFunction);
+ if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
+ LexicalDC->addDeclInternal(ToFunction);
+
+ // Friend declaration's lexical context is the befriending class, but the
+ // semantic context is the enclosing scope of the befriending class.
+ // We want the friend functions to be found in the semantic context by lookup.
+ // FIXME should we handle this generically in VisitFriendDecl?
+ // In Other cases when LexicalDC != DC we don't want it to be added,
+ // e.g out-of-class definitions like void B::f() {} .
+ if (LexicalDC != DC && IsFriend) {
+ DC->makeDeclVisibleInContext(ToFunction);
+ }
+
+ // Import the rest of the chain. I.e. import all subsequent declarations.
+ for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt)
+ if (!Importer.Import(*RedeclIt))
+ return nullptr;
if (auto *FromCXXMethod = dyn_cast<CXXMethodDecl>(D))
ImportOverrides(cast<CXXMethodDecl>(ToFunction), FromCXXMethod);
@@ -2278,7 +2824,7 @@ Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
}
static unsigned getFieldIndex(Decl *F) {
- RecordDecl *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
+ auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
if (!Owner)
return 0;
@@ -2308,15 +2854,15 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
// Determine whether we've already imported this field.
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
+ for (auto *FoundDecl : FoundDecls) {
+ if (auto *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
// For anonymous fields, match up by index.
if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
continue;
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundField->getType())) {
- Importer.Imported(D, FoundField);
+ Importer.MapImported(D, FoundField);
return FoundField;
}
@@ -2338,11 +2884,13 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
if (!BitWidth && D->getBitWidth())
return nullptr;
- FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()),
- Loc, Name.getAsIdentifierInfo(),
- T, TInfo, BitWidth, D->isMutable(),
- D->getInClassInitStyle());
+ FieldDecl *ToField;
+ if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
+ Importer.Import(D->getInnerLocStart()), Loc,
+ Name.getAsIdentifierInfo(), T, TInfo, BitWidth,
+ D->isMutable(), D->getInClassInitStyle()))
+ return ToField;
+
ToField->setAccess(D->getAccess());
ToField->setLexicalDeclContext(LexicalDC);
if (Expr *FromInitializer = D->getInClassInitializer()) {
@@ -2353,7 +2901,6 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
return nullptr;
}
ToField->setImplicit(D->isImplicit());
- Importer.Imported(D, ToField);
LexicalDC->addDeclInternal(ToField);
return ToField;
}
@@ -2373,8 +2920,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (IndirectFieldDecl *FoundField
- = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
+ if (auto *FoundField = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
// For anonymous indirect fields, match up by index.
if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
continue;
@@ -2382,7 +2928,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundField->getType(),
!Name.isEmpty())) {
- Importer.Imported(D, FoundField);
+ Importer.MapImported(D, FoundField);
return FoundField;
}
@@ -2403,8 +2949,8 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
if (T.isNull())
return nullptr;
- NamedDecl **NamedChain =
- new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
+ auto **NamedChain =
+ new (Importer.getToContext()) NamedDecl*[D->getChainingSize()];
unsigned i = 0;
for (auto *PI : D->chain()) {
@@ -2414,16 +2960,18 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
NamedChain[i++] = cast<NamedDecl>(D);
}
- IndirectFieldDecl *ToIndirectField = IndirectFieldDecl::Create(
- Importer.getToContext(), DC, Loc, Name.getAsIdentifierInfo(), T,
- {NamedChain, D->getChainingSize()});
+ llvm::MutableArrayRef<NamedDecl *> CH = {NamedChain, D->getChainingSize()};
+ IndirectFieldDecl *ToIndirectField;
+ if (GetImportedOrCreateDecl(ToIndirectField, D, Importer.getToContext(), DC,
+ Loc, Name.getAsIdentifierInfo(), T, CH))
+ // FIXME here we leak `NamedChain` which is allocated before
+ return ToIndirectField;
- for (const auto *Attr : D->attrs())
- ToIndirectField->addAttr(Attr->clone(Importer.getToContext()));
+ for (const auto *A : D->attrs())
+ ToIndirectField->addAttr(Importer.Import(A));
ToIndirectField->setAccess(D->getAccess());
ToIndirectField->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToIndirectField);
LexicalDC->addDeclInternal(ToIndirectField);
return ToIndirectField;
}
@@ -2440,37 +2988,38 @@ Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
// FriendDecl is not a NamedDecl so we cannot use localUncachedLookup.
auto *RD = cast<CXXRecordDecl>(DC);
FriendDecl *ImportedFriend = RD->getFirstFriend();
- StructuralEquivalenceContext Context(
- Importer.getFromContext(), Importer.getToContext(),
- Importer.getNonEquivalentDecls(), false, false);
while (ImportedFriend) {
if (D->getFriendDecl() && ImportedFriend->getFriendDecl()) {
- if (Context.IsStructurallyEquivalent(D->getFriendDecl(),
- ImportedFriend->getFriendDecl()))
- return Importer.Imported(D, ImportedFriend);
+ if (IsStructuralMatch(D->getFriendDecl(), ImportedFriend->getFriendDecl(),
+ /*Complain=*/false))
+ return Importer.MapImported(D, ImportedFriend);
} else if (D->getFriendType() && ImportedFriend->getFriendType()) {
if (Importer.IsStructurallyEquivalent(
D->getFriendType()->getType(),
ImportedFriend->getFriendType()->getType(), true))
- return Importer.Imported(D, ImportedFriend);
+ return Importer.MapImported(D, ImportedFriend);
}
ImportedFriend = ImportedFriend->getNextFriend();
}
// Not found. Create it.
FriendDecl::FriendUnion ToFU;
- if (NamedDecl *FriendD = D->getFriendDecl())
- ToFU = cast_or_null<NamedDecl>(Importer.Import(FriendD));
- else
+ if (NamedDecl *FriendD = D->getFriendDecl()) {
+ auto *ToFriendD = cast_or_null<NamedDecl>(Importer.Import(FriendD));
+ if (ToFriendD && FriendD->getFriendObjectKind() != Decl::FOK_None &&
+ !(FriendD->isInIdentifierNamespace(Decl::IDNS_NonMemberOperator)))
+ ToFriendD->setObjectOfFriendDecl(false);
+
+ ToFU = ToFriendD;
+ } else // The friend is a type, not a decl.
ToFU = Importer.Import(D->getFriendType());
if (!ToFU)
return nullptr;
SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
- TemplateParameterList **FromTPLists =
- D->getTrailingObjects<TemplateParameterList *>();
+ auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0; I < D->NumTPLists; I++) {
TemplateParameterList *List = ImportTemplateParameterList(FromTPLists[I]);
if (!List)
@@ -2478,13 +3027,11 @@ Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
ToTPLists[I] = List;
}
- FriendDecl *FrD = FriendDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getLocation()),
- ToFU, Importer.Import(D->getFriendLoc()),
- ToTPLists);
-
- Importer.Imported(D, FrD);
- RD->pushFriendDecl(FrD);
+ FriendDecl *FrD;
+ if (GetImportedOrCreateDecl(FrD, D, Importer.getToContext(), DC,
+ Importer.Import(D->getLocation()), ToFU,
+ Importer.Import(D->getFriendLoc()), ToTPLists))
+ return FrD;
FrD->setAccess(D->getAccess());
FrD->setLexicalDeclContext(LexicalDC);
@@ -2506,11 +3053,11 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
// Determine whether we've already imported this ivar
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
+ for (auto *FoundDecl : FoundDecls) {
+ if (auto *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundIvar->getType())) {
- Importer.Imported(D, FoundIvar);
+ Importer.MapImported(D, FoundIvar);
return FoundIvar;
}
@@ -2532,17 +3079,17 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
if (!BitWidth && D->getBitWidth())
return nullptr;
- ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
- cast<ObjCContainerDecl>(DC),
- Importer.Import(D->getInnerLocStart()),
- Loc, Name.getAsIdentifierInfo(),
- T, TInfo, D->getAccessControl(),
- BitWidth, D->getSynthesize());
+ ObjCIvarDecl *ToIvar;
+ if (GetImportedOrCreateDecl(
+ ToIvar, D, Importer.getToContext(), cast<ObjCContainerDecl>(DC),
+ Importer.Import(D->getInnerLocStart()), Loc,
+ Name.getAsIdentifierInfo(), T, TInfo, D->getAccessControl(), BitWidth,
+ D->getSynthesize()))
+ return ToIvar;
+
ToIvar->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToIvar);
LexicalDC->addDeclInternal(ToIvar);
return ToIvar;
-
}
Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
@@ -2564,11 +3111,11 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
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))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
+ if (auto *FoundVar = dyn_cast<VarDecl>(FoundDecl)) {
// We have found a variable that we may need to merge with. Check it.
if (FoundVar->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
@@ -2607,14 +3154,15 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
}
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (MergeWithVar) {
- // An equivalent variable with external linkage has been found. Link
+ // An equivalent variable with external linkage has been found. Link
// the two declarations, then merge them.
- Importer.Imported(D, MergeWithVar);
-
+ Importer.MapImported(D, MergeWithVar);
+ updateFlags(D, MergeWithVar);
+
if (VarDecl *DDef = D->getDefinition()) {
if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
Importer.ToDiag(ExistingDef->getLocation(),
@@ -2651,20 +3199,20 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Create the imported variable.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()),
- Loc, Name.getAsIdentifierInfo(),
- T, TInfo,
- D->getStorageClass());
+ VarDecl *ToVar;
+ if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
+ Importer.Import(D->getInnerLocStart()), Loc,
+ Name.getAsIdentifierInfo(), T, TInfo,
+ D->getStorageClass()))
+ return ToVar;
+
ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
ToVar->setAccess(D->getAccess());
ToVar->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToVar);
- LexicalDC->addDeclInternal(ToVar);
- if (!D->isFileVarDecl() &&
- D->isUsed())
- ToVar->setIsUsed();
+ // Templated declarations should never appear in the enclosing DeclContext.
+ if (!D->getDescribedVarTemplate())
+ LexicalDC->addDeclInternal(ToVar);
// Merge the initializer.
if (ImportDefinition(D, ToVar))
@@ -2695,10 +3243,12 @@ Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
return nullptr;
// Create the imported parameter.
- auto *ToParm = ImplicitParamDecl::Create(Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(), T,
- D->getParameterKind());
- return Importer.Imported(D, ToParm);
+ ImplicitParamDecl *ToParm = nullptr;
+ if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC, Loc,
+ Name.getAsIdentifierInfo(), T,
+ D->getParameterKind()))
+ return ToParm;
+ return ToParm;
}
Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
@@ -2721,11 +3271,13 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
// Create the imported parameter.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()),
- Loc, Name.getAsIdentifierInfo(),
- T, TInfo, D->getStorageClass(),
- /*DefaultArg*/ nullptr);
+ ParmVarDecl *ToParm;
+ if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
+ Importer.Import(D->getInnerLocStart()), Loc,
+ Name.getAsIdentifierInfo(), T, TInfo,
+ D->getStorageClass(),
+ /*DefaultArg*/ nullptr))
+ return ToParm;
// Set the default argument.
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
@@ -2747,10 +3299,15 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
if (FromDefArg && !ToDefArg)
return nullptr;
- if (D->isUsed())
- ToParm->setIsUsed();
+ if (D->isObjCMethodParameter()) {
+ ToParm->setObjCMethodScopeInfo(D->getFunctionScopeIndex());
+ ToParm->setObjCDeclQualifier(D->getObjCDeclQualifier());
+ } else {
+ ToParm->setScopeInfo(D->getFunctionScopeDepth(),
+ D->getFunctionScopeIndex());
+ }
- return Importer.Imported(D, ToParm);
+ return ToParm;
}
Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
@@ -2766,8 +3323,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (ObjCMethodDecl *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecls[I])) {
+ for (auto *FoundDecl : FoundDecls) {
+ if (auto *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecl)) {
if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
continue;
@@ -2822,7 +3379,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
}
// FIXME: Any other bits we need to merge?
- return Importer.Imported(D, FoundMethod);
+ return Importer.MapImported(D, FoundMethod);
}
}
@@ -2833,11 +3390,14 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
- ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create(
- Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()),
- Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(),
- D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
- D->getImplementationControl(), D->hasRelatedResultType());
+ ObjCMethodDecl *ToMethod;
+ if (GetImportedOrCreateDecl(
+ ToMethod, D, Importer.getToContext(), Loc,
+ Importer.Import(D->getLocEnd()), Name.getObjCSelector(), ResultTy,
+ ReturnTInfo, DC, D->isInstanceMethod(), D->isVariadic(),
+ D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
+ D->getImplementationControl(), D->hasRelatedResultType()))
+ return ToMethod;
// FIXME: When we decide to merge method definitions, we'll need to
// deal with implicit parameters.
@@ -2845,7 +3405,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Import the parameters
SmallVector<ParmVarDecl *, 5> ToParams;
for (auto *FromP : D->parameters()) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
+ auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
if (!ToP)
return nullptr;
@@ -2853,16 +3413,19 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
}
// Set the parameters.
- for (unsigned I = 0, N = ToParams.size(); I != N; ++I) {
- ToParams[I]->setOwningFunction(ToMethod);
- ToMethod->addDeclInternal(ToParams[I]);
+ for (auto *ToParam : ToParams) {
+ ToParam->setOwningFunction(ToMethod);
+ ToMethod->addDeclInternal(ToParam);
}
+
SmallVector<SourceLocation, 12> SelLocs;
D->getSelectorLocs(SelLocs);
- ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
+ for (auto &Loc : SelLocs)
+ Loc = Importer.Import(Loc);
+
+ ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
ToMethod->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToMethod);
LexicalDC->addDeclInternal(ToMethod);
return ToMethod;
}
@@ -2882,16 +3445,14 @@ Decl *ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
if (!BoundInfo)
return nullptr;
- ObjCTypeParamDecl *Result = ObjCTypeParamDecl::Create(
- Importer.getToContext(), DC,
- D->getVariance(),
- Importer.Import(D->getVarianceLoc()),
- D->getIndex(),
- Importer.Import(D->getLocation()),
- Name.getAsIdentifierInfo(),
- Importer.Import(D->getColonLoc()),
- BoundInfo);
- Importer.Imported(D, Result);
+ ObjCTypeParamDecl *Result;
+ if (GetImportedOrCreateDecl(
+ Result, D, Importer.getToContext(), DC, D->getVariance(),
+ Importer.Import(D->getVarianceLoc()), D->getIndex(),
+ Importer.Import(D->getLocation()), Name.getAsIdentifierInfo(),
+ Importer.Import(D->getColonLoc()), BoundInfo))
+ return Result;
+
Result->setLexicalDeclContext(LexicalDC);
return Result;
}
@@ -2907,8 +3468,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
if (ToD)
return ToD;
- ObjCInterfaceDecl *ToInterface
- = cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
+ auto *ToInterface =
+ cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
if (!ToInterface)
return nullptr;
@@ -2917,18 +3478,18 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
= ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
ObjCCategoryDecl *ToCategory = MergeWithCategory;
if (!ToCategory) {
- ToCategory = ObjCCategoryDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getAtStartLoc()),
- Loc,
- Importer.Import(D->getCategoryNameLoc()),
- Name.getAsIdentifierInfo(),
- ToInterface,
- /*TypeParamList=*/nullptr,
- Importer.Import(D->getIvarLBraceLoc()),
- Importer.Import(D->getIvarRBraceLoc()));
+
+ if (GetImportedOrCreateDecl(ToCategory, D, Importer.getToContext(), DC,
+ Importer.Import(D->getAtStartLoc()), Loc,
+ Importer.Import(D->getCategoryNameLoc()),
+ Name.getAsIdentifierInfo(), ToInterface,
+ /*TypeParamList=*/nullptr,
+ Importer.Import(D->getIvarLBraceLoc()),
+ Importer.Import(D->getIvarRBraceLoc())))
+ return ToCategory;
+
ToCategory->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToCategory);
- Importer.Imported(D, ToCategory);
// Import the type parameter list after calling Imported, to avoid
// loops when bringing in their DeclContext.
ToCategory->setTypeParamList(ImportObjCTypeParamList(
@@ -2943,8 +3504,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
FromProtoEnd = D->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- ObjCProtocolDecl *ToProto
- = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+ auto *ToProto =
+ cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
return nullptr;
Protocols.push_back(ToProto);
@@ -2954,9 +3515,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
// FIXME: If we're merging, make sure that the protocol list is the same.
ToCategory->setProtocolList(Protocols.data(), Protocols.size(),
ProtocolLocs.data(), Importer.getToContext());
-
} else {
- Importer.Imported(D, ToCategory);
+ Importer.MapImported(D, ToCategory);
}
// Import all of the members of this category.
@@ -2964,8 +3524,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
// If we have an implementation, import it as well.
if (D->getImplementation()) {
- ObjCCategoryImplDecl *Impl
- = cast_or_null<ObjCCategoryImplDecl>(
+ auto *Impl =
+ cast_or_null<ObjCCategoryImplDecl>(
Importer.Import(D->getImplementation()));
if (!Impl)
return nullptr;
@@ -2997,8 +3557,7 @@ bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
FromProtoEnd = From->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- ObjCProtocolDecl *ToProto
- = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+ auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
return true;
Protocols.push_back(ToProto);
@@ -3026,7 +3585,7 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
// Import the major distinguishing characteristics of a protocol.
@@ -3042,25 +3601,26 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
ObjCProtocolDecl *MergeWithProtocol = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
continue;
- if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecls[I])))
+ if ((MergeWithProtocol = dyn_cast<ObjCProtocolDecl>(FoundDecl)))
break;
}
ObjCProtocolDecl *ToProto = MergeWithProtocol;
if (!ToProto) {
- ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
- Name.getAsIdentifierInfo(), Loc,
- Importer.Import(D->getAtStartLoc()),
- /*PrevDecl=*/nullptr);
+ if (GetImportedOrCreateDecl(ToProto, D, Importer.getToContext(), DC,
+ Name.getAsIdentifierInfo(), Loc,
+ Importer.Import(D->getAtStartLoc()),
+ /*PrevDecl=*/nullptr))
+ return ToProto;
ToProto->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProto);
}
-
- Importer.Imported(D, ToProto);
+
+ Importer.MapImported(D, ToProto);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
return nullptr;
@@ -3076,14 +3636,11 @@ Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
SourceLocation LangLoc = Importer.Import(D->getLocation());
bool HasBraces = D->hasBraces();
-
- LinkageSpecDecl *ToLinkageSpec =
- LinkageSpecDecl::Create(Importer.getToContext(),
- DC,
- ExternLoc,
- LangLoc,
- D->getLanguage(),
- HasBraces);
+
+ LinkageSpecDecl *ToLinkageSpec;
+ if (GetImportedOrCreateDecl(ToLinkageSpec, D, Importer.getToContext(), DC,
+ ExternLoc, LangLoc, D->getLanguage(), HasBraces))
+ return ToLinkageSpec;
if (HasBraces) {
SourceLocation RBraceLoc = Importer.Import(D->getRBraceLoc());
@@ -3093,8 +3650,6 @@ Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
ToLinkageSpec->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToLinkageSpec);
- Importer.Imported(D, ToLinkageSpec);
-
return ToLinkageSpec;
}
@@ -3112,26 +3667,28 @@ Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
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());
+ UsingDecl *ToUsing;
+ if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
+ Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getQualifierLoc()), NameInfo,
+ D->hasTypename()))
+ return ToUsing;
+
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)))
+ if (auto *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)))
+ for (auto *FromShadow : D->shadows()) {
+ if (auto *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
@@ -3151,27 +3708,28 @@ Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
if (ToD)
return ToD;
- UsingDecl *ToUsing = dyn_cast_or_null<UsingDecl>(
- Importer.Import(D->getUsingDecl()));
+ auto *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()));
+ auto *ToTarget = dyn_cast_or_null<NamedDecl>(
+ Importer.Import(D->getTargetDecl()));
if (!ToTarget)
return nullptr;
- UsingShadowDecl *ToShadow = UsingShadowDecl::Create(
- Importer.getToContext(), DC, Loc, ToUsing, ToTarget);
+ UsingShadowDecl *ToShadow;
+ if (GetImportedOrCreateDecl(ToShadow, D, Importer.getToContext(), DC, Loc,
+ ToUsing, ToTarget))
+ return ToShadow;
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)))
+ if (auto *ToPattern =
+ dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern)))
Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow,
ToPattern);
else
@@ -3185,7 +3743,6 @@ Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
return ToShadow;
}
-
Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -3200,19 +3757,22 @@ Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
if (!ToComAncestor)
return nullptr;
- NamespaceDecl *ToNominated = cast_or_null<NamespaceDecl>(
- Importer.Import(D->getNominatedNamespace()));
+ auto *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);
+ UsingDirectiveDecl *ToUsingDir;
+ if (GetImportedOrCreateDecl(ToUsingDir, D, Importer.getToContext(), DC,
+ Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getNamespaceKeyLocation()),
+ Importer.Import(D->getQualifierLoc()),
+ Importer.Import(D->getIdentLocation()),
+ ToNominated, ToComAncestor))
+ return ToUsingDir;
+
ToUsingDir->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToUsingDir);
- Importer.Imported(D, ToUsingDir);
return ToUsingDir;
}
@@ -3231,12 +3791,13 @@ Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl(
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()));
+ UnresolvedUsingValueDecl *ToUsingValue;
+ if (GetImportedOrCreateDecl(ToUsingValue, D, Importer.getToContext(), DC,
+ Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getQualifierLoc()), NameInfo,
+ Importer.Import(D->getEllipsisLoc())))
+ return ToUsingValue;
- Importer.Imported(D, ToUsingValue);
ToUsingValue->setAccess(D->getAccess());
ToUsingValue->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToUsingValue);
@@ -3255,13 +3816,14 @@ Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
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()));
+ UnresolvedUsingTypenameDecl *ToUsing;
+ if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
+ Importer.Import(D->getUsingLoc()),
+ Importer.Import(D->getTypenameLoc()),
+ Importer.Import(D->getQualifierLoc()), Loc, Name,
+ Importer.Import(D->getEllipsisLoc())))
+ return ToUsing;
- Importer.Imported(D, ToUsing);
ToUsing->setAccess(D->getAccess());
ToUsing->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToUsing);
@@ -3269,7 +3831,6 @@ Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
return ToUsing;
}
-
bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
ObjCInterfaceDecl *To,
ImportDefinitionKind Kind) {
@@ -3330,8 +3891,7 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
FromProtoEnd = From->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- ObjCProtocolDecl *ToProto
- = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
+ auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
return true;
Protocols.push_back(ToProto);
@@ -3349,8 +3909,8 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// If we have an @implementation, import it as well.
if (From->getImplementation()) {
- ObjCImplementationDecl *Impl = cast_or_null<ObjCImplementationDecl>(
- Importer.Import(From->getImplementation()));
+ auto *Impl = cast_or_null<ObjCImplementationDecl>(
+ Importer.Import(From->getImplementation()));
if (!Impl)
return true;
@@ -3371,8 +3931,8 @@ ASTNodeImporter::ImportObjCTypeParamList(ObjCTypeParamList *list) {
SmallVector<ObjCTypeParamDecl *, 4> toTypeParams;
for (auto fromTypeParam : *list) {
- auto toTypeParam = cast_or_null<ObjCTypeParamDecl>(
- Importer.Import(fromTypeParam));
+ auto *toTypeParam = cast_or_null<ObjCTypeParamDecl>(
+ Importer.Import(fromTypeParam));
if (!toTypeParam)
return nullptr;
@@ -3395,7 +3955,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
// Import the major distinguishing characteristics of an @interface.
@@ -3412,27 +3972,27 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
ObjCInterfaceDecl *MergeWithIface = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
continue;
- if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecls[I])))
+ if ((MergeWithIface = dyn_cast<ObjCInterfaceDecl>(FoundDecl)))
break;
}
// Create an interface declaration, if one does not already exist.
ObjCInterfaceDecl *ToIface = MergeWithIface;
if (!ToIface) {
- ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getAtStartLoc()),
- Name.getAsIdentifierInfo(),
- /*TypeParamList=*/nullptr,
- /*PrevDecl=*/nullptr, Loc,
- D->isImplicitInterfaceDecl());
+ if (GetImportedOrCreateDecl(
+ ToIface, D, Importer.getToContext(), DC,
+ Importer.Import(D->getAtStartLoc()), Name.getAsIdentifierInfo(),
+ /*TypeParamList=*/nullptr,
+ /*PrevDecl=*/nullptr, Loc, D->isImplicitInterfaceDecl()))
+ return ToIface;
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
}
- Importer.Imported(D, ToIface);
+ Importer.MapImported(D, ToIface);
// Import the type parameter list after calling Imported, to avoid
// loops when bringing in their DeclContext.
ToIface->setTypeParamList(ImportObjCTypeParamList(
@@ -3445,8 +4005,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
}
Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
- Importer.Import(D->getCategoryDecl()));
+ auto *Category = cast_or_null<ObjCCategoryDecl>(
+ Importer.Import(D->getCategoryDecl()));
if (!Category)
return nullptr;
@@ -3457,13 +4017,13 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
return nullptr;
SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
- ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getIdentifier()),
- Category->getClassInterface(),
- Importer.Import(D->getLocation()),
- Importer.Import(D->getAtStartLoc()),
- CategoryNameLoc);
-
+ if (GetImportedOrCreateDecl(
+ ToImpl, D, Importer.getToContext(), DC,
+ Importer.Import(D->getIdentifier()), Category->getClassInterface(),
+ Importer.Import(D->getLocation()),
+ Importer.Import(D->getAtStartLoc()), CategoryNameLoc))
+ return ToImpl;
+
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
@@ -3477,15 +4037,15 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
Category->setImplementation(ToImpl);
}
- Importer.Imported(D, ToImpl);
+ Importer.MapImported(D, ToImpl);
ImportDeclContext(D);
return ToImpl;
}
Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
// Find the corresponding interface.
- ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
- Importer.Import(D->getClassInterface()));
+ auto *Iface = cast_or_null<ObjCInterfaceDecl>(
+ Importer.Import(D->getClassInterface()));
if (!Iface)
return nullptr;
@@ -3502,15 +4062,15 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
if (!Impl) {
// We haven't imported an implementation yet. Create a new @implementation
// now.
- Impl = ObjCImplementationDecl::Create(Importer.getToContext(),
- Importer.ImportContext(D->getDeclContext()),
- Iface, Super,
- Importer.Import(D->getLocation()),
- Importer.Import(D->getAtStartLoc()),
- Importer.Import(D->getSuperClassLoc()),
- Importer.Import(D->getIvarLBraceLoc()),
- Importer.Import(D->getIvarRBraceLoc()));
-
+ if (GetImportedOrCreateDecl(Impl, D, Importer.getToContext(),
+ Importer.ImportContext(D->getDeclContext()),
+ Iface, Super, Importer.Import(D->getLocation()),
+ Importer.Import(D->getAtStartLoc()),
+ Importer.Import(D->getSuperClassLoc()),
+ Importer.Import(D->getIvarLBraceLoc()),
+ Importer.Import(D->getIvarRBraceLoc())))
+ return Impl;
+
if (D->getDeclContext() != D->getLexicalDeclContext()) {
DeclContext *LexicalDC
= Importer.ImportContext(D->getLexicalDeclContext());
@@ -3518,12 +4078,12 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
return nullptr;
Impl->setLexicalDeclContext(LexicalDC);
}
-
+
// Associate the implementation with the class it implements.
Iface->setImplementation(Impl);
- Importer.Imported(D, Iface->getImplementation());
+ Importer.MapImported(D, Iface->getImplementation());
} else {
- Importer.Imported(D, Iface->getImplementation());
+ Importer.MapImported(D, Iface->getImplementation());
// Verify that the existing @implementation has the same superclass.
if ((Super && !Impl->getSuperClass()) ||
@@ -3574,9 +4134,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Check whether we have already imported this property.
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (ObjCPropertyDecl *FoundProp
- = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) {
+ for (auto *FoundDecl : FoundDecls) {
+ if (auto *FoundProp = dyn_cast<ObjCPropertyDecl>(FoundDecl)) {
// Check property types.
if (!Importer.IsStructurallyEquivalent(D->getType(),
FoundProp->getType())) {
@@ -3590,7 +4149,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// FIXME: Check property attributes, getters, setters, etc.?
// Consider these properties to be equivalent.
- Importer.Imported(D, FoundProp);
+ Importer.MapImported(D, FoundProp);
return FoundProp;
}
}
@@ -3601,15 +4160,14 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
return nullptr;
// Create the new property.
- ObjCPropertyDecl *ToProperty
- = ObjCPropertyDecl::Create(Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(),
- Importer.Import(D->getAtLoc()),
- Importer.Import(D->getLParenLoc()),
- Importer.Import(D->getType()),
- TSI,
- D->getPropertyImplementation());
- Importer.Imported(D, ToProperty);
+ ObjCPropertyDecl *ToProperty;
+ if (GetImportedOrCreateDecl(
+ ToProperty, D, Importer.getToContext(), DC, Loc,
+ Name.getAsIdentifierInfo(), Importer.Import(D->getAtLoc()),
+ Importer.Import(D->getLParenLoc()), Importer.Import(D->getType()),
+ TSI, D->getPropertyImplementation()))
+ return ToProperty;
+
ToProperty->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProperty);
@@ -3630,8 +4188,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
}
Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
- Importer.Import(D->getPropertyDecl()));
+ auto *Property = cast_or_null<ObjCPropertyDecl>(
+ Importer.Import(D->getPropertyDecl()));
if (!Property)
return nullptr;
@@ -3647,7 +4205,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
return nullptr;
}
- ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
+ auto *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
if (!InImpl)
return nullptr;
@@ -3663,16 +4221,15 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
ObjCPropertyImplDecl *ToImpl
= InImpl->FindPropertyImplDecl(Property->getIdentifier(),
Property->getQueryKind());
- if (!ToImpl) {
- ToImpl = ObjCPropertyImplDecl::Create(Importer.getToContext(), DC,
- Importer.Import(D->getLocStart()),
- Importer.Import(D->getLocation()),
- Property,
- D->getPropertyImplementation(),
- Ivar,
- Importer.Import(D->getPropertyIvarDeclLoc()));
+ if (!ToImpl) {
+ if (GetImportedOrCreateDecl(ToImpl, D, Importer.getToContext(), DC,
+ Importer.Import(D->getLocStart()),
+ Importer.Import(D->getLocation()), Property,
+ D->getPropertyImplementation(), Ivar,
+ Importer.Import(D->getPropertyIvarDeclLoc())))
+ return ToImpl;
+
ToImpl->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToImpl);
LexicalDC->addDeclInternal(ToImpl);
} else {
// Check that we have the same kind of property implementation (@synthesize
@@ -3705,7 +4262,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
}
// Merge the existing implementation with the new implementation.
- Importer.Imported(D, ToImpl);
+ Importer.MapImported(D, ToImpl);
}
return ToImpl;
@@ -3717,15 +4274,14 @@ Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
// is created.
// FIXME: Import default argument.
- return TemplateTypeParmDecl::Create(Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- Importer.Import(D->getLocStart()),
- Importer.Import(D->getLocation()),
- D->getDepth(),
- D->getIndex(),
- Importer.Import(D->getIdentifier()),
- D->wasDeclaredWithTypename(),
- D->isParameterPack());
+ TemplateTypeParmDecl *ToD = nullptr;
+ (void)GetImportedOrCreateDecl(
+ ToD, D, Importer.getToContext(),
+ Importer.getToContext().getTranslationUnitDecl(),
+ Importer.Import(D->getLocStart()), Importer.Import(D->getLocation()),
+ D->getDepth(), D->getIndex(), Importer.Import(D->getIdentifier()),
+ D->wasDeclaredWithTypename(), D->isParameterPack());
+ return ToD;
}
Decl *
@@ -3749,13 +4305,15 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
return nullptr;
// FIXME: Import default argument.
-
- return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- Importer.Import(D->getInnerLocStart()),
- Loc, D->getDepth(), D->getPosition(),
- Name.getAsIdentifierInfo(),
- T, D->isParameterPack(), TInfo);
+
+ NonTypeTemplateParmDecl *ToD = nullptr;
+ (void)GetImportedOrCreateDecl(
+ ToD, D, Importer.getToContext(),
+ Importer.getToContext().getTranslationUnitDecl(),
+ Importer.Import(D->getInnerLocStart()), Loc, D->getDepth(),
+ D->getPosition(), Name.getAsIdentifierInfo(), T, D->isParameterPack(),
+ TInfo);
+ return ToD;
}
Decl *
@@ -3767,7 +4325,7 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
-
+
// Import template parameters.
TemplateParameterList *TemplateParams
= ImportTemplateParameterList(D->getTemplateParameters());
@@ -3775,30 +4333,42 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
return nullptr;
// FIXME: Import default argument.
-
- return TemplateTemplateParmDecl::Create(Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(),
- Loc, D->getDepth(), D->getPosition(),
- D->isParameterPack(),
- Name.getAsIdentifierInfo(),
- TemplateParams);
+
+ TemplateTemplateParmDecl *ToD = nullptr;
+ (void)GetImportedOrCreateDecl(
+ ToD, D, Importer.getToContext(),
+ Importer.getToContext().getTranslationUnitDecl(), Loc, D->getDepth(),
+ D->getPosition(), D->isParameterPack(), Name.getAsIdentifierInfo(),
+ TemplateParams);
+ return ToD;
+}
+
+// Returns the definition for a (forward) declaration of a ClassTemplateDecl, if
+// it has any definition in the redecl chain.
+static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
+ CXXRecordDecl *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
+ if (!ToTemplatedDef)
+ return nullptr;
+ ClassTemplateDecl *TemplateWithDef =
+ ToTemplatedDef->getDescribedClassTemplate();
+ return TemplateWithDef;
}
Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// If this record has a definition in the translation unit we're coming from,
// but this particular declaration is not that definition, import the
// definition and map to that.
- CXXRecordDecl *Definition
- = cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
+ auto *Definition =
+ cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
if (Definition && Definition != D->getTemplatedDecl()) {
Decl *ImportedDef
= Importer.Import(Definition->getDescribedClassTemplate());
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
-
+
// Import the major distinguishing characteristics of this class template.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -3814,69 +4384,73 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
continue;
-
- Decl *Found = FoundDecls[I];
- if (ClassTemplateDecl *FoundTemplate
- = dyn_cast<ClassTemplateDecl>(Found)) {
+
+ Decl *Found = FoundDecl;
+ if (auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found)) {
+
+ // The class to be imported is a definition.
+ if (D->isThisDeclarationADefinition()) {
+ // Lookup will find the fwd decl only if that is more recent than the
+ // definition. So, try to get the definition if that is available in
+ // the redecl chain.
+ ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+ if (!TemplateWithDef)
+ continue;
+ FoundTemplate = TemplateWithDef; // Continue with the definition.
+ }
+
if (IsStructuralMatch(D, FoundTemplate)) {
// The class templates structurally match; call it the same template.
- // FIXME: We may be filling in a forward declaration here. Handle
- // this case!
- Importer.Imported(D->getTemplatedDecl(),
- FoundTemplate->getTemplatedDecl());
- return Importer.Imported(D, FoundTemplate);
- }
+
+ Importer.MapImported(D->getTemplatedDecl(),
+ FoundTemplate->getTemplatedDecl());
+ return Importer.MapImported(D, FoundTemplate);
+ }
}
-
- ConflictingDecls.push_back(FoundDecls[I]);
+
+ ConflictingDecls.push_back(FoundDecl);
}
-
+
if (!ConflictingDecls.empty()) {
Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Ordinary,
- ConflictingDecls.data(),
+ ConflictingDecls.data(),
ConflictingDecls.size());
}
-
+
if (!Name)
return nullptr;
}
- CXXRecordDecl *DTemplated = D->getTemplatedDecl();
-
+ CXXRecordDecl *FromTemplated = D->getTemplatedDecl();
+
// Create the declaration that is being templated.
- CXXRecordDecl *D2Templated = cast_or_null<CXXRecordDecl>(
- Importer.Import(DTemplated));
- if (!D2Templated)
+ auto *ToTemplated = cast_or_null<CXXRecordDecl>(
+ Importer.Import(FromTemplated));
+ if (!ToTemplated)
return nullptr;
- // Resolve possible cyclic import.
- if (Decl *AlreadyImported = Importer.GetAlreadyImportedOrNull(D))
- return AlreadyImported;
-
// Create the class template declaration itself.
- TemplateParameterList *TemplateParams
- = ImportTemplateParameterList(D->getTemplateParameters());
+ TemplateParameterList *TemplateParams =
+ ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
return nullptr;
- ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
- Loc, Name, TemplateParams,
- D2Templated);
- D2Templated->setDescribedClassTemplate(D2);
+ ClassTemplateDecl *D2;
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name,
+ TemplateParams, ToTemplated))
+ return D2;
+
+ ToTemplated->setDescribedClassTemplate(D2);
D2->setAccess(D->getAccess());
D2->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(D2);
- // Note the relationship between the class templates.
- Importer.Imported(D, D2);
- Importer.Imported(DTemplated, D2Templated);
-
- if (DTemplated->isCompleteDefinition() &&
- !D2Templated->isCompleteDefinition()) {
+ if (FromTemplated->isCompleteDefinition() &&
+ !ToTemplated->isCompleteDefinition()) {
// FIXME: Import definition!
}
@@ -3894,11 +4468,11 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
- ClassTemplateDecl *ClassTemplate
- = cast_or_null<ClassTemplateDecl>(Importer.Import(
+ auto *ClassTemplate =
+ cast_or_null<ClassTemplateDecl>(Importer.Import(
D->getSpecializedTemplate()));
if (!ClassTemplate)
return nullptr;
@@ -3941,23 +4515,18 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
// The record types structurally match, or the "from" translation
// unit only had a forward declaration anyway; call it the same
// function.
- return Importer.Imported(D, FoundDef);
+ return Importer.MapImported(D, FoundDef);
}
}
} else {
// Create a new specialization.
- if (ClassTemplatePartialSpecializationDecl *PartialSpec =
- dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
-
+ if (auto *PartialSpec =
+ dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
// Import TemplateArgumentListInfo
TemplateArgumentListInfo ToTAInfo;
- auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
- for (unsigned I = 0, E = ASTTemplateArgs.NumTemplateArgs; I < E; ++I) {
- if (auto ToLoc = ImportTemplateArgumentLoc(ASTTemplateArgs[I]))
- ToTAInfo.addArgument(*ToLoc);
- else
- return nullptr;
- }
+ const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
+ if (ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
+ return nullptr;
QualType CanonInjType = Importer.Import(
PartialSpec->getInjectedSpecializationType());
@@ -3970,19 +4539,18 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (!ToTPList && PartialSpec->getTemplateParameters())
return nullptr;
- D2 = ClassTemplatePartialSpecializationDecl::Create(
- Importer.getToContext(), D->getTagKind(), DC, StartLoc, IdLoc,
- ToTPList, ClassTemplate,
- llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
- ToTAInfo, CanonInjType, nullptr);
+ if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
+ IdLoc, ToTPList, ClassTemplate,
+ llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
+ ToTAInfo, CanonInjType, nullptr))
+ return D2;
} else {
- D2 = ClassTemplateSpecializationDecl::Create(Importer.getToContext(),
- D->getTagKind(), DC,
- StartLoc, IdLoc,
- ClassTemplate,
- TemplateArgs,
- /*PrevDecl=*/nullptr);
+ if (GetImportedOrCreateDecl(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
+ IdLoc, ClassTemplate, TemplateArgs, /*PrevDecl=*/nullptr))
+ return D2;
}
D2->setSpecializationKind(D->getSpecializationKind());
@@ -3993,8 +4561,6 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
// Import the qualifier, if any.
D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
- Importer.Imported(D, D2);
-
if (auto *TSI = D->getTypeAsWritten()) {
TypeSourceInfo *TInfo = Importer.Import(TSI);
if (!TInfo)
@@ -4012,11 +4578,14 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
- // Add the specialization to this context.
+ // Set the context of this specialization/instantiation.
D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
+
+ // Add to the DC only if it was an explicit specialization/instantiation.
+ if (D2->isExplicitInstantiationOrSpecialization()) {
+ LexicalDC->addDeclInternal(D2);
+ }
}
- Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
return nullptr;
@@ -4028,14 +4597,14 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
// from,
// but this particular declaration is not that definition, import the
// definition and map to that.
- VarDecl *Definition =
+ auto *Definition =
cast_or_null<VarDecl>(D->getTemplatedDecl()->getDefinition());
if (Definition && Definition != D->getTemplatedDecl()) {
Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
// Import the major distinguishing characteristics of this variable template.
@@ -4054,21 +4623,21 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
- for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
- if (!FoundDecls[I]->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
continue;
- Decl *Found = FoundDecls[I];
- if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
+ Decl *Found = FoundDecl;
+ if (auto *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
if (IsStructuralMatch(D, FoundTemplate)) {
// The variable templates structurally match; call it the same template.
- Importer.Imported(D->getTemplatedDecl(),
- FoundTemplate->getTemplatedDecl());
- return Importer.Imported(D, FoundTemplate);
+ Importer.MapImported(D->getTemplatedDecl(),
+ FoundTemplate->getTemplatedDecl());
+ return Importer.MapImported(D, FoundTemplate);
}
}
- ConflictingDecls.push_back(FoundDecls[I]);
+ ConflictingDecls.push_back(FoundDecl);
}
if (!ConflictingDecls.empty()) {
@@ -4088,21 +4657,8 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
return nullptr;
// Create the declaration that is being templated.
- SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
- SourceLocation IdLoc = Importer.Import(DTemplated->getLocation());
- TypeSourceInfo *TInfo = Importer.Import(DTemplated->getTypeSourceInfo());
- VarDecl *D2Templated = VarDecl::Create(Importer.getToContext(), DC, StartLoc,
- IdLoc, Name.getAsIdentifierInfo(), T,
- TInfo, DTemplated->getStorageClass());
- D2Templated->setAccess(DTemplated->getAccess());
- D2Templated->setQualifierInfo(Importer.Import(DTemplated->getQualifierLoc()));
- D2Templated->setLexicalDeclContext(LexicalDC);
-
- // Importer.Imported(DTemplated, D2Templated);
- // LexicalDC->addDeclInternal(D2Templated);
-
- // Merge the initializer.
- if (ImportDefinition(DTemplated, D2Templated))
+ auto *ToTemplated = dyn_cast_or_null<VarDecl>(Importer.Import(DTemplated));
+ if (!ToTemplated)
return nullptr;
// Create the variable template declaration itself.
@@ -4111,24 +4667,23 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
if (!TemplateParams)
return nullptr;
- VarTemplateDecl *D2 = VarTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
- D2Templated->setDescribedVarTemplate(D2);
+ VarTemplateDecl *ToVarTD;
+ if (GetImportedOrCreateDecl(ToVarTD, D, Importer.getToContext(), DC, Loc,
+ Name, TemplateParams, ToTemplated))
+ return ToVarTD;
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
+ ToTemplated->setDescribedVarTemplate(ToVarTD);
- // Note the relationship between the variable templates.
- Importer.Imported(D, D2);
- Importer.Imported(DTemplated, D2Templated);
+ ToVarTD->setAccess(D->getAccess());
+ ToVarTD->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(ToVarTD);
if (DTemplated->isThisDeclarationADefinition() &&
- !D2Templated->isThisDeclarationADefinition()) {
+ !ToTemplated->isThisDeclarationADefinition()) {
// FIXME: Import definition!
}
- return D2;
+ return ToVarTD;
}
Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
@@ -4142,10 +4697,10 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
if (!ImportedDef)
return nullptr;
- return Importer.Imported(D, ImportedDef);
+ return Importer.MapImported(D, ImportedDef);
}
- VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
+ auto *VarTemplate = cast_or_null<VarTemplateDecl>(
Importer.Import(D->getSpecializedTemplate()));
if (!VarTemplate)
return nullptr;
@@ -4188,23 +4743,68 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
// The record types structurally match, or the "from" translation
// unit only had a forward declaration anyway; call it the same
// variable.
- return Importer.Imported(D, FoundDef);
+ return Importer.MapImported(D, FoundDef);
}
}
} else {
-
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
return nullptr;
+
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
+ if (D->getTypeSourceInfo() && !TInfo)
+ return nullptr;
+
+ TemplateArgumentListInfo ToTAInfo;
+ if (ImportTemplateArgumentListInfo(D->getTemplateArgsInfo(), ToTAInfo))
+ return nullptr;
+ using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
// Create a new specialization.
- D2 = VarTemplateSpecializationDecl::Create(
- Importer.getToContext(), DC, StartLoc, IdLoc, VarTemplate, T, TInfo,
- D->getStorageClass(), TemplateArgs);
+ if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
+ // Import TemplateArgumentListInfo
+ TemplateArgumentListInfo ArgInfos;
+ const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
+ // NOTE: FromTAArgsAsWritten and template parameter list are non-null.
+ if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
+ return nullptr;
+
+ TemplateParameterList *ToTPList = ImportTemplateParameterList(
+ FromPartial->getTemplateParameters());
+ if (!ToTPList)
+ return nullptr;
+
+ PartVarSpecDecl *ToPartial;
+ if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
+ StartLoc, IdLoc, ToTPList, VarTemplate, T,
+ TInfo, D->getStorageClass(), TemplateArgs,
+ ArgInfos))
+ return ToPartial;
+
+ auto *FromInst = FromPartial->getInstantiatedFromMember();
+ auto *ToInst = cast_or_null<PartVarSpecDecl>(Importer.Import(FromInst));
+ if (FromInst && !ToInst)
+ return nullptr;
+
+ ToPartial->setInstantiatedFromMember(ToInst);
+ if (FromPartial->isMemberSpecialization())
+ ToPartial->setMemberSpecialization();
+
+ D2 = ToPartial;
+ } else { // Full specialization
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, StartLoc,
+ IdLoc, VarTemplate, T, TInfo,
+ D->getStorageClass(), TemplateArgs))
+ return D2;
+ }
+
+ SourceLocation POI = D->getPointOfInstantiation();
+ if (POI.isValid())
+ D2->setPointOfInstantiation(Importer.Import(POI));
+
D2->setSpecializationKind(D->getSpecializationKind());
- D2->setTemplateArgsInfo(D->getTemplateArgsInfo());
+ D2->setTemplateArgsInfo(ToTAInfo);
// Add this specialization to the class template.
VarTemplate->AddSpecialization(D2, InsertPos);
@@ -4212,13 +4812,22 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
// Import the qualifier, if any.
D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ if (D->isConstexpr())
+ D2->setConstexpr(true);
+
// Add the specialization to this context.
D2->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(D2);
+
+ D2->setAccess(D->getAccess());
}
- Importer.Imported(D, D2);
- if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
+ // NOTE: isThisDeclarationADefinition() can return DeclarationOnly even if
+ // declaration has initializer. Should this be fixed in the AST?.. Anyway,
+ // we have to check the declaration for initializer - otherwise, it won't be
+ // imported.
+ if ((D->isThisDeclarationADefinition() || D->hasInit()) &&
+ ImportDefinition(D, D2))
return nullptr;
return D2;
@@ -4242,16 +4851,15 @@ Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
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))
+ for (auto *FoundDecl : FoundDecls) {
+ if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (FunctionTemplateDecl *FoundFunction =
- dyn_cast<FunctionTemplateDecl>(FoundDecls[I])) {
+ if (auto *FoundFunction = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
if (FoundFunction->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
if (IsStructuralMatch(D, FoundFunction)) {
- Importer.Imported(D, FoundFunction);
+ Importer.MapImported(D, FoundFunction);
// FIXME: Actually try to merge the body and other attributes.
return FoundFunction;
}
@@ -4265,18 +4873,19 @@ Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (!Params)
return nullptr;
- FunctionDecl *TemplatedFD =
+ auto *TemplatedFD =
cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl()));
if (!TemplatedFD)
return nullptr;
- FunctionTemplateDecl *ToFunc = FunctionTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, Params, TemplatedFD);
+ FunctionTemplateDecl *ToFunc;
+ if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
+ Params, TemplatedFD))
+ return ToFunc;
TemplatedFD->setDescribedFunctionTemplate(ToFunc);
ToFunc->setAccess(D->getAccess());
ToFunc->setLexicalDeclContext(LexicalDC);
- Importer.Imported(D, ToFunc);
LexicalDC->addDeclInternal(ToFunc);
return ToFunc;
@@ -4301,12 +4910,11 @@ DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) {
NumDecls);
}
- Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
- Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
- << S->getStmtClassName();
- return nullptr;
- }
-
+Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
+ Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
+ << S->getStmtClassName();
+ return nullptr;
+}
Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
SmallVector<IdentifierInfo *, 4> Names;
@@ -4329,8 +4937,8 @@ Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
SmallVector<StringLiteral *, 4> Clobbers;
for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) {
- StringLiteral *Clobber = cast_or_null<StringLiteral>(
- Importer.Import(S->getClobberStringLiteral(I)));
+ auto *Clobber = cast_or_null<StringLiteral>(
+ Importer.Import(S->getClobberStringLiteral(I)));
if (!Clobber)
return nullptr;
Clobbers.push_back(Clobber);
@@ -4338,16 +4946,16 @@ Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
SmallVector<StringLiteral *, 4> Constraints;
for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
- StringLiteral *Output = cast_or_null<StringLiteral>(
- Importer.Import(S->getOutputConstraintLiteral(I)));
+ auto *Output = cast_or_null<StringLiteral>(
+ Importer.Import(S->getOutputConstraintLiteral(I)));
if (!Output)
return nullptr;
Constraints.push_back(Output);
}
for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
- StringLiteral *Input = cast_or_null<StringLiteral>(
- Importer.Import(S->getInputConstraintLiteral(I)));
+ auto *Input = cast_or_null<StringLiteral>(
+ Importer.Import(S->getInputConstraintLiteral(I)));
if (!Input)
return nullptr;
Constraints.push_back(Input);
@@ -4360,8 +4968,8 @@ Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
if (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
return nullptr;
- StringLiteral *AsmStr = cast_or_null<StringLiteral>(
- Importer.Import(S->getAsmString()));
+ auto *AsmStr = cast_or_null<StringLiteral>(
+ Importer.Import(S->getAsmString()));
if (!AsmStr)
return nullptr;
@@ -4383,7 +4991,7 @@ Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup());
- for (Decl *ToD : ToDG) {
+ for (auto *ToD : ToDG) {
if (!ToD)
return nullptr;
}
@@ -4399,7 +5007,7 @@ Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) {
}
Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
- llvm::SmallVector<Stmt *, 8> ToStmts(S->size());
+ SmallVector<Stmt *, 8> ToStmts(S->size());
if (ImportContainerChecked(S->body(), ToStmts))
return nullptr;
@@ -4423,7 +5031,7 @@ Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc());
SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc());
SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
- CaseStmt *ToStmt = new (Importer.getToContext())
+ auto *ToStmt = new (Importer.getToContext())
CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
ToStmt->setSubStmt(ToSubStmt);
return ToStmt;
@@ -4441,8 +5049,7 @@ Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
Stmt *ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
SourceLocation ToIdentLoc = Importer.Import(S->getIdentLoc());
- LabelDecl *ToLabelDecl =
- cast_or_null<LabelDecl>(Importer.Import(S->getDecl()));
+ auto *ToLabelDecl = cast_or_null<LabelDecl>(Importer.Import(S->getDecl()));
if (!ToLabelDecl && S->getDecl())
return nullptr;
Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
@@ -4456,15 +5063,8 @@ Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc());
ArrayRef<const Attr*> FromAttrs(S->getAttrs());
SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
- ASTContext &_ToContext = Importer.getToContext();
- std::transform(FromAttrs.begin(), FromAttrs.end(), ToAttrs.begin(),
- [&_ToContext](const Attr *A) -> const Attr * {
- return A->clone(_ToContext);
- });
- for (const Attr *ToA : ToAttrs) {
- if (!ToA)
- return nullptr;
- }
+ if (ImportContainerChecked(FromAttrs, ToAttrs))
+ return nullptr;
Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
if (!ToSubStmt && S->getSubStmt())
return nullptr;
@@ -4516,7 +5116,7 @@ Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
Expr *ToCondition = Importer.Import(S->getCond());
if (!ToCondition && S->getCond())
return nullptr;
- SwitchStmt *ToStmt = new (Importer.getToContext()) SwitchStmt(
+ auto *ToStmt = new (Importer.getToContext()) SwitchStmt(
Importer.getToContext(), ToInit,
ToConditionVariable, ToCondition);
Stmt *ToBody = Importer.Import(S->getBody());
@@ -4528,7 +5128,7 @@ Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
SwitchCase *LastChainedSwitchCase = nullptr;
for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr;
SC = SC->getNextSwitchCase()) {
- SwitchCase *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC));
+ auto *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC));
if (!ToSC)
return nullptr;
if (LastChainedSwitchCase)
@@ -4645,8 +5245,8 @@ Stmt *ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
Expr *ToRetExpr = Importer.Import(S->getRetValue());
if (!ToRetExpr && S->getRetValue())
return nullptr;
- VarDecl *NRVOCandidate = const_cast<VarDecl*>(S->getNRVOCandidate());
- VarDecl *ToNRVOCandidate = cast_or_null<VarDecl>(Importer.Import(NRVOCandidate));
+ auto *NRVOCandidate = const_cast<VarDecl *>(S->getNRVOCandidate());
+ auto *ToNRVOCandidate = cast_or_null<VarDecl>(Importer.Import(NRVOCandidate));
if (!ToNRVOCandidate && NRVOCandidate)
return nullptr;
return new (Importer.getToContext()) ReturnStmt(ToRetLoc, ToRetExpr,
@@ -4688,15 +5288,15 @@ Stmt *ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
}
Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
- DeclStmt *ToRange =
+ auto *ToRange =
dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt()));
if (!ToRange && S->getRangeStmt())
return nullptr;
- DeclStmt *ToBegin =
+ auto *ToBegin =
dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginStmt()));
if (!ToBegin && S->getBeginStmt())
return nullptr;
- DeclStmt *ToEnd =
+ auto *ToEnd =
dyn_cast_or_null<DeclStmt>(Importer.Import(S->getEndStmt()));
if (!ToEnd && S->getEndStmt())
return nullptr;
@@ -4706,7 +5306,7 @@ Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
Expr *ToInc = Importer.Import(S->getInc());
if (!ToInc && S->getInc())
return nullptr;
- DeclStmt *ToLoopVar =
+ auto *ToLoopVar =
dyn_cast_or_null<DeclStmt>(Importer.Import(S->getLoopVarStmt()));
if (!ToLoopVar && S->getLoopVarStmt())
return nullptr;
@@ -4851,7 +5451,6 @@ Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI());
}
-
Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
@@ -4866,8 +5465,7 @@ Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
if (T.isNull())
return nullptr;
- StringLiteral *SL = cast_or_null<StringLiteral>(
- Importer.Import(E->getFunctionName()));
+ auto *SL = cast_or_null<StringLiteral>(Importer.Import(E->getFunctionName()));
if (!SL && E->getFunctionName())
return nullptr;
@@ -4876,7 +5474,7 @@ Expr *ASTNodeImporter::VisitPredefinedExpr(PredefinedExpr *E) {
}
Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
- ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
+ auto *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
if (!ToD)
return nullptr;
@@ -4891,16 +5489,11 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
if (T.isNull())
return nullptr;
-
TemplateArgumentListInfo ToTAInfo;
TemplateArgumentListInfo *ResInfo = nullptr;
if (E->hasExplicitTemplateArgs()) {
- for (const auto &FromLoc : E->template_arguments()) {
- if (auto ToTALoc = ImportTemplateArgumentLoc(FromLoc))
- ToTAInfo.addArgument(*ToTALoc);
- else
- return nullptr;
- }
+ if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+ return nullptr;
ResInfo = &ToTAInfo;
}
@@ -4947,14 +5540,14 @@ ASTNodeImporter::ImportDesignator(const Designator &D) {
Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) {
- Expr *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit()));
+ auto *Init = cast_or_null<Expr>(Importer.Import(DIE->getInit()));
if (!Init)
return nullptr;
SmallVector<Expr *, 4> IndexExprs(DIE->getNumSubExprs() - 1);
// List elements from the second, the first is Init itself
for (unsigned I = 1, E = DIE->getNumSubExprs(); I < E; I++) {
- if (Expr *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I))))
+ if (auto *Arg = cast_or_null<Expr>(Importer.Import(DIE->getSubExpr(I))))
IndexExprs[I - 1] = Arg;
else
return nullptr;
@@ -4966,7 +5559,7 @@ Expr *ASTNodeImporter::VisitDesignatedInitExpr(DesignatedInitExpr *DIE) {
return ImportDesignator(D);
});
- for (const Designator &D : DIE->designators())
+ for (const auto &D : DIE->designators())
if (D.isFieldDesignator() && !D.getFieldName())
return nullptr;
@@ -5067,7 +5660,7 @@ Expr *ASTNodeImporter::VisitAddrLabelExpr(AddrLabelExpr *E) {
if (T.isNull())
return nullptr;
- LabelDecl *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel()));
+ auto *ToLabel = cast_or_null<LabelDecl>(Importer.Import(E->getLabel()));
if (!ToLabel)
return nullptr;
@@ -5102,8 +5695,8 @@ Expr *ASTNodeImporter::VisitStmtExpr(StmtExpr *E) {
if (T.isNull())
return nullptr;
- CompoundStmt *ToSubStmt = cast_or_null<CompoundStmt>(
- Importer.Import(E->getSubStmt()));
+ auto *ToSubStmt = cast_or_null<CompoundStmt>(
+ Importer.Import(E->getSubStmt()));
if (!ToSubStmt && E->getSubStmt())
return nullptr;
@@ -5120,14 +5713,13 @@ Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
if (!SubExpr)
return nullptr;
- return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
- T, E->getValueKind(),
- E->getObjectKind(),
- Importer.Import(E->getOperatorLoc()));
+ return new (Importer.getToContext()) UnaryOperator(
+ SubExpr, E->getOpcode(), T, E->getValueKind(), E->getObjectKind(),
+ Importer.Import(E->getOperatorLoc()), E->canOverflow());
}
-Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
- UnaryExprOrTypeTraitExpr *E) {
+Expr *
+ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
QualType ResultType = Importer.Import(E->getType());
if (E->isArgumentType()) {
@@ -5208,8 +5800,8 @@ Expr *ASTNodeImporter::VisitBinaryConditionalOperator(
if (!Cond)
return nullptr;
- OpaqueValueExpr *OpaqueValue = cast_or_null<OpaqueValueExpr>(
- Importer.Import(E->getOpaqueValue()));
+ auto *OpaqueValue = cast_or_null<OpaqueValueExpr>(
+ Importer.Import(E->getOpaqueValue()));
if (!OpaqueValue)
return nullptr;
@@ -5367,7 +5959,7 @@ Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
switch (E->getStmtClass()) {
case Stmt::CStyleCastExprClass: {
- CStyleCastExpr *CCE = cast<CStyleCastExpr>(E);
+ auto *CCE = cast<CStyleCastExpr>(E);
return CStyleCastExpr::Create(Importer.getToContext(), T,
E->getValueKind(), E->getCastKind(),
SubExpr, &BasePath, TInfo,
@@ -5376,7 +5968,7 @@ Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
}
case Stmt::CXXFunctionalCastExprClass: {
- CXXFunctionalCastExpr *FCE = cast<CXXFunctionalCastExpr>(E);
+ auto *FCE = cast<CXXFunctionalCastExpr>(E);
return CXXFunctionalCastExpr::Create(Importer.getToContext(), T,
E->getValueKind(), TInfo,
E->getCastKind(), SubExpr, &BasePath,
@@ -5385,7 +5977,7 @@ Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
}
case Stmt::ObjCBridgedCastExprClass: {
- ObjCBridgedCastExpr *OCE = cast<ObjCBridgedCastExpr>(E);
+ auto *OCE = cast<ObjCBridgedCastExpr>(E);
return new (Importer.getToContext()) ObjCBridgedCastExpr(
Importer.Import(OCE->getLParenLoc()), OCE->getBridgeKind(),
E->getCastKind(), Importer.Import(OCE->getBridgeKeywordLoc()),
@@ -5395,7 +5987,7 @@ Expr *ASTNodeImporter::VisitExplicitCastExpr(ExplicitCastExpr *E) {
break; // just fall through
}
- CXXNamedCastExpr *Named = cast<CXXNamedCastExpr>(E);
+ auto *Named = cast<CXXNamedCastExpr>(E);
SourceLocation ExprLoc = Importer.Import(Named->getOperatorLoc()),
RParenLoc = Importer.Import(Named->getRParenLoc());
SourceRange Brackets = Importer.Import(Named->getAngleBrackets());
@@ -5453,7 +6045,7 @@ Expr *ASTNodeImporter::VisitOffsetOfExpr(OffsetOfExpr *OE) {
break;
}
case OffsetOfNode::Field: {
- FieldDecl *FD = cast_or_null<FieldDecl>(Importer.Import(Node.getField()));
+ auto *FD = cast_or_null<FieldDecl>(Importer.Import(Node.getField()));
if (!FD)
return nullptr;
Nodes.push_back(OffsetOfNode(Importer.Import(Node.getLocStart()), FD,
@@ -5524,8 +6116,7 @@ Expr *ASTNodeImporter::VisitCXXThrowExpr(CXXThrowExpr *E) {
}
Expr *ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
- ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
- Importer.Import(E->getParam()));
+ auto *Param = cast_or_null<ParmVarDecl>(Importer.Import(E->getParam()));
if (!Param)
return nullptr;
@@ -5567,6 +6158,10 @@ Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
if (T.isNull())
return nullptr;
+ TypeSourceInfo *TInfo = Importer.Import(CE->getTypeSourceInfo());
+ if (!TInfo)
+ return nullptr;
+
SmallVector<Expr *, 8> Args(CE->getNumArgs());
if (ImportContainerChecked(CE->arguments(), Args))
return nullptr;
@@ -5576,18 +6171,11 @@ Expr *ASTNodeImporter::VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *CE) {
if (!Ctor)
return nullptr;
- return CXXTemporaryObjectExpr::Create(
- Importer.getToContext(), T,
- Importer.Import(CE->getLocStart()),
- Ctor,
- CE->isElidable(),
- Args,
- CE->hadMultipleCandidates(),
- CE->isListInitialization(),
- CE->isStdInitListInitialization(),
- CE->requiresZeroInitialization(),
- CE->getConstructionKind(),
- Importer.Import(CE->getParenOrBraceRange()));
+ return new (Importer.getToContext()) CXXTemporaryObjectExpr(
+ Importer.getToContext(), Ctor, T, TInfo, Args,
+ Importer.Import(CE->getParenOrBraceRange()), CE->hadMultipleCandidates(),
+ CE->isListInitialization(), CE->isStdInitListInitialization(),
+ CE->requiresZeroInitialization());
}
Expr *
@@ -5600,7 +6188,7 @@ ASTNodeImporter::VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
if (!TempE)
return nullptr;
- ValueDecl *ExtendedBy = cast_or_null<ValueDecl>(
+ auto *ExtendedBy = cast_or_null<ValueDecl>(
Importer.Import(const_cast<ValueDecl *>(E->getExtendingDecl())));
if (!ExtendedBy && E->getExtendingDecl())
return nullptr;
@@ -5627,6 +6215,30 @@ Expr *ASTNodeImporter::VisitPackExpansionExpr(PackExpansionExpr *E) {
E->getNumExpansions());
}
+Expr *ASTNodeImporter::VisitSizeOfPackExpr(SizeOfPackExpr *E) {
+ auto *Pack = cast_or_null<NamedDecl>(Importer.Import(E->getPack()));
+ if (!Pack)
+ return nullptr;
+
+ Optional<unsigned> Length;
+
+ if (!E->isValueDependent())
+ Length = E->getPackLength();
+
+ SmallVector<TemplateArgument, 8> PartialArguments;
+ if (E->isPartiallySubstituted()) {
+ if (ImportTemplateArguments(E->getPartialArguments().data(),
+ E->getPartialArguments().size(),
+ PartialArguments))
+ return nullptr;
+ }
+
+ return SizeOfPackExpr::Create(
+ Importer.getToContext(), Importer.Import(E->getOperatorLoc()), Pack,
+ Importer.Import(E->getPackLoc()), Importer.Import(E->getRParenLoc()),
+ Length, PartialArguments);
+}
+
Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
QualType T = Importer.Import(CE->getType());
if (T.isNull())
@@ -5636,12 +6248,12 @@ Expr *ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *CE) {
if (ImportContainerChecked(CE->placement_arguments(), PlacementArgs))
return nullptr;
- FunctionDecl *OperatorNewDecl = cast_or_null<FunctionDecl>(
+ auto *OperatorNewDecl = cast_or_null<FunctionDecl>(
Importer.Import(CE->getOperatorNew()));
if (!OperatorNewDecl && CE->getOperatorNew())
return nullptr;
- FunctionDecl *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
+ auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
Importer.Import(CE->getOperatorDelete()));
if (!OperatorDeleteDecl && CE->getOperatorDelete())
return nullptr;
@@ -5676,7 +6288,7 @@ Expr *ASTNodeImporter::VisitCXXDeleteExpr(CXXDeleteExpr *E) {
if (T.isNull())
return nullptr;
- FunctionDecl *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
+ auto *OperatorDeleteDecl = cast_or_null<FunctionDecl>(
Importer.Import(E->getOperatorDelete()));
if (!OperatorDeleteDecl && E->getOperatorDelete())
return nullptr;
@@ -5700,7 +6312,7 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
if (T.isNull())
return nullptr;
- CXXConstructorDecl *ToCCD =
+ auto *ToCCD =
dyn_cast_or_null<CXXConstructorDecl>(Importer.Import(E->getConstructor()));
if (!ToCCD)
return nullptr;
@@ -5784,13 +6396,17 @@ Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
if (!ToBase && E->getBase())
return nullptr;
- ValueDecl *ToMember = dyn_cast<ValueDecl>(Importer.Import(E->getMemberDecl()));
+ auto *ToMember = dyn_cast<ValueDecl>(Importer.Import(E->getMemberDecl()));
if (!ToMember && E->getMemberDecl())
return nullptr;
- DeclAccessPair ToFoundDecl = DeclAccessPair::make(
- dyn_cast<NamedDecl>(Importer.Import(E->getFoundDecl().getDecl())),
- E->getFoundDecl().getAccess());
+ auto *ToDecl =
+ dyn_cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl().getDecl()));
+ if (!ToDecl && E->getFoundDecl().getDecl())
+ return nullptr;
+
+ DeclAccessPair ToFoundDecl =
+ DeclAccessPair::make(ToDecl, E->getFoundDecl().getAccess());
DeclarationNameInfo ToMemberNameInfo(
Importer.Import(E->getMemberNameInfo().getName()),
@@ -5812,7 +6428,6 @@ Expr *ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
Expr *ASTNodeImporter::VisitCXXPseudoDestructorExpr(
CXXPseudoDestructorExpr *E) {
-
Expr *BaseE = Importer.Import(E->getBase());
if (!BaseE)
return nullptr;
@@ -5856,11 +6471,10 @@ Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
if (BaseType.isNull())
return nullptr;
- TemplateArgumentListInfo ToTAInfo(Importer.Import(E->getLAngleLoc()),
- Importer.Import(E->getRAngleLoc()));
- TemplateArgumentListInfo *ResInfo = nullptr;
+ TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
if (E->hasExplicitTemplateArgs()) {
- if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+ if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
+ E->template_arguments(), ToTAInfo))
return nullptr;
ResInfo = &ToTAInfo;
}
@@ -5884,6 +6498,127 @@ Expr *ASTNodeImporter::VisitCXXDependentScopeMemberExpr(
cast_or_null<NamedDecl>(ToFQ), MemberNameInfo, ResInfo);
}
+Expr *
+ASTNodeImporter::VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+ DeclarationName Name = Importer.Import(E->getDeclName());
+ if (!E->getDeclName().isEmpty() && Name.isEmpty())
+ return nullptr;
+
+ DeclarationNameInfo NameInfo(Name, Importer.Import(E->getExprLoc()));
+ ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+
+ 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;
+ }
+
+ return DependentScopeDeclRefExpr::Create(
+ Importer.getToContext(), Importer.Import(E->getQualifierLoc()),
+ Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo);
+}
+
+Expr *ASTNodeImporter::VisitCXXUnresolvedConstructExpr(
+ CXXUnresolvedConstructExpr *CE) {
+ unsigned NumArgs = CE->arg_size();
+
+ SmallVector<Expr *, 8> ToArgs(NumArgs);
+ if (ImportArrayChecked(CE->arg_begin(), CE->arg_end(), ToArgs.begin()))
+ return nullptr;
+
+ return CXXUnresolvedConstructExpr::Create(
+ Importer.getToContext(), Importer.Import(CE->getTypeSourceInfo()),
+ Importer.Import(CE->getLParenLoc()), llvm::makeArrayRef(ToArgs),
+ Importer.Import(CE->getRParenLoc()));
+}
+
+Expr *ASTNodeImporter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E) {
+ auto *NamingClass =
+ cast_or_null<CXXRecordDecl>(Importer.Import(E->getNamingClass()));
+ if (E->getNamingClass() && !NamingClass)
+ return nullptr;
+
+ DeclarationName Name = Importer.Import(E->getName());
+ if (E->getName() && !Name)
+ return nullptr;
+
+ DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc()));
+ // Import additional name location/type info.
+ ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+
+ UnresolvedSet<8> ToDecls;
+ for (auto *D : E->decls()) {
+ if (auto *To = cast_or_null<NamedDecl>(Importer.Import(D)))
+ ToDecls.addDecl(To);
+ else
+ return nullptr;
+ }
+
+ TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
+ if (E->hasExplicitTemplateArgs()) {
+ if (ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
+ E->template_arguments(), ToTAInfo))
+ return nullptr;
+ ResInfo = &ToTAInfo;
+ }
+
+ if (ResInfo || E->getTemplateKeywordLoc().isValid())
+ return UnresolvedLookupExpr::Create(
+ Importer.getToContext(), NamingClass,
+ Importer.Import(E->getQualifierLoc()),
+ Importer.Import(E->getTemplateKeywordLoc()), NameInfo, E->requiresADL(),
+ ResInfo, ToDecls.begin(), ToDecls.end());
+
+ return UnresolvedLookupExpr::Create(
+ Importer.getToContext(), NamingClass,
+ Importer.Import(E->getQualifierLoc()), NameInfo, E->requiresADL(),
+ E->isOverloaded(), ToDecls.begin(), ToDecls.end());
+}
+
+Expr *ASTNodeImporter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E) {
+ DeclarationName Name = Importer.Import(E->getName());
+ if (!E->getName().isEmpty() && Name.isEmpty())
+ return nullptr;
+ DeclarationNameInfo NameInfo(Name, Importer.Import(E->getNameLoc()));
+ // Import additional name location/type info.
+ ImportDeclarationNameLoc(E->getNameInfo(), NameInfo);
+
+ QualType BaseType = Importer.Import(E->getType());
+ if (!E->getType().isNull() && BaseType.isNull())
+ return nullptr;
+
+ UnresolvedSet<8> ToDecls;
+ for (Decl *D : E->decls()) {
+ if (NamedDecl *To = cast_or_null<NamedDecl>(Importer.Import(D)))
+ ToDecls.addDecl(To);
+ else
+ return nullptr;
+ }
+
+ TemplateArgumentListInfo ToTAInfo;
+ TemplateArgumentListInfo *ResInfo = nullptr;
+ if (E->hasExplicitTemplateArgs()) {
+ if (ImportTemplateArgumentListInfo(E->template_arguments(), ToTAInfo))
+ return nullptr;
+ ResInfo = &ToTAInfo;
+ }
+
+ Expr *BaseE = E->isImplicitAccess() ? nullptr : Importer.Import(E->getBase());
+ if (!BaseE && !E->isImplicitAccess() && E->getBase()) {
+ return nullptr;
+ }
+
+ return UnresolvedMemberExpr::Create(
+ Importer.getToContext(), E->hasUnresolvedUsing(), BaseE, BaseType,
+ E->isArrow(), Importer.Import(E->getOperatorLoc()),
+ Importer.Import(E->getQualifierLoc()),
+ Importer.Import(E->getTemplateKeywordLoc()), NameInfo, ResInfo,
+ ToDecls.begin(), ToDecls.end());
+}
+
Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
@@ -5894,35 +6629,100 @@ Expr *ASTNodeImporter::VisitCallExpr(CallExpr *E) {
return nullptr;
unsigned NumArgs = E->getNumArgs();
+ SmallVector<Expr *, 2> ToArgs(NumArgs);
+ if (ImportContainerChecked(E->arguments(), ToArgs))
+ return nullptr;
- llvm::SmallVector<Expr *, 2> ToArgs(NumArgs);
-
- for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai) {
- Expr *FromArg = E->getArg(ai);
- Expr *ToArg = Importer.Import(FromArg);
- if (!ToArg)
- return nullptr;
- ToArgs[ai] = ToArg;
- }
-
- Expr **ToArgs_Copied = new (Importer.getToContext())
- Expr*[NumArgs];
+ auto **ToArgs_Copied = new (Importer.getToContext()) Expr*[NumArgs];
for (unsigned ai = 0, ae = NumArgs; ai != ae; ++ai)
ToArgs_Copied[ai] = ToArgs[ai];
+ if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
+ return new (Importer.getToContext()) CXXOperatorCallExpr(
+ Importer.getToContext(), OCE->getOperator(), ToCallee, ToArgs, T,
+ OCE->getValueKind(), Importer.Import(OCE->getRParenLoc()),
+ OCE->getFPFeatures());
+ }
+
return new (Importer.getToContext())
CallExpr(Importer.getToContext(), ToCallee,
llvm::makeArrayRef(ToArgs_Copied, NumArgs), T, E->getValueKind(),
Importer.Import(E->getRParenLoc()));
}
+Optional<LambdaCapture>
+ASTNodeImporter::ImportLambdaCapture(const LambdaCapture &From) {
+ VarDecl *Var = nullptr;
+ if (From.capturesVariable()) {
+ Var = cast_or_null<VarDecl>(Importer.Import(From.getCapturedVar()));
+ if (!Var)
+ return None;
+ }
+
+ return LambdaCapture(Importer.Import(From.getLocation()), From.isImplicit(),
+ From.getCaptureKind(), Var,
+ From.isPackExpansion()
+ ? Importer.Import(From.getEllipsisLoc())
+ : SourceLocation());
+}
+
+Expr *ASTNodeImporter::VisitLambdaExpr(LambdaExpr *LE) {
+ CXXRecordDecl *FromClass = LE->getLambdaClass();
+ auto *ToClass = dyn_cast_or_null<CXXRecordDecl>(Importer.Import(FromClass));
+ if (!ToClass)
+ return nullptr;
+
+ // NOTE: lambda classes are created with BeingDefined flag set up.
+ // It means that ImportDefinition doesn't work for them and we should fill it
+ // manually.
+ if (ToClass->isBeingDefined()) {
+ for (auto FromField : FromClass->fields()) {
+ auto *ToField = cast_or_null<FieldDecl>(Importer.Import(FromField));
+ if (!ToField)
+ return nullptr;
+ }
+ }
+
+ auto *ToCallOp = dyn_cast_or_null<CXXMethodDecl>(
+ Importer.Import(LE->getCallOperator()));
+ if (!ToCallOp)
+ return nullptr;
+
+ ToClass->completeDefinition();
+
+ unsigned NumCaptures = LE->capture_size();
+ SmallVector<LambdaCapture, 8> Captures;
+ Captures.reserve(NumCaptures);
+ for (const auto &FromCapture : LE->captures()) {
+ if (auto ToCapture = ImportLambdaCapture(FromCapture))
+ Captures.push_back(*ToCapture);
+ else
+ return nullptr;
+ }
+
+ SmallVector<Expr *, 8> InitCaptures(NumCaptures);
+ if (ImportContainerChecked(LE->capture_inits(), InitCaptures))
+ return nullptr;
+
+ return LambdaExpr::Create(Importer.getToContext(), ToClass,
+ Importer.Import(LE->getIntroducerRange()),
+ LE->getCaptureDefault(),
+ Importer.Import(LE->getCaptureDefaultLoc()),
+ Captures,
+ LE->hasExplicitParameters(),
+ LE->hasExplicitResultType(),
+ InitCaptures,
+ Importer.Import(LE->getLocEnd()),
+ LE->containsUnexpandedParameterPack());
+}
+
Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) {
QualType T = Importer.Import(ILE->getType());
if (T.isNull())
return nullptr;
- llvm::SmallVector<Expr *, 4> Exprs(ILE->getNumInits());
+ SmallVector<Expr *, 4> Exprs(ILE->getNumInits());
if (ImportContainerChecked(ILE->inits(), Exprs))
return nullptr;
@@ -5940,15 +6740,14 @@ Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) {
}
if (FieldDecl *FromFD = ILE->getInitializedFieldInUnion()) {
- FieldDecl *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD));
+ auto *ToFD = cast_or_null<FieldDecl>(Importer.Import(FromFD));
if (!ToFD)
return nullptr;
To->setInitializedFieldInUnion(ToFD);
}
if (InitListExpr *SyntForm = ILE->getSyntacticForm()) {
- InitListExpr *ToSyntForm = cast_or_null<InitListExpr>(
- Importer.Import(SyntForm));
+ auto *ToSyntForm = cast_or_null<InitListExpr>(Importer.Import(SyntForm));
if (!ToSyntForm)
return nullptr;
To->setSyntacticForm(ToSyntForm);
@@ -5961,6 +6760,35 @@ Expr *ASTNodeImporter::VisitInitListExpr(InitListExpr *ILE) {
return To;
}
+Expr *ASTNodeImporter::VisitCXXStdInitializerListExpr(
+ CXXStdInitializerListExpr *E) {
+ QualType T = Importer.Import(E->getType());
+ if (T.isNull())
+ return nullptr;
+
+ Expr *SE = Importer.Import(E->getSubExpr());
+ if (!SE)
+ return nullptr;
+
+ return new (Importer.getToContext()) CXXStdInitializerListExpr(T, SE);
+}
+
+Expr *ASTNodeImporter::VisitCXXInheritedCtorInitExpr(
+ CXXInheritedCtorInitExpr *E) {
+ QualType T = Importer.Import(E->getType());
+ if (T.isNull())
+ return nullptr;
+
+ auto *Ctor = cast_or_null<CXXConstructorDecl>(Importer.Import(
+ E->getConstructor()));
+ if (!Ctor)
+ return nullptr;
+
+ return new (Importer.getToContext()) CXXInheritedCtorInitExpr(
+ Importer.Import(E->getLocation()), T, Ctor,
+ E->constructsVBase(), E->inheritedFromVBase());
+}
+
Expr *ASTNodeImporter::VisitArrayInitLoopExpr(ArrayInitLoopExpr *E) {
QualType ToType = Importer.Import(E->getType());
if (ToType.isNull())
@@ -5986,8 +6814,7 @@ Expr *ASTNodeImporter::VisitArrayInitIndexExpr(ArrayInitIndexExpr *E) {
}
Expr *ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
- FieldDecl *ToField = llvm::dyn_cast_or_null<FieldDecl>(
- Importer.Import(DIE->getField()));
+ auto *ToField = dyn_cast_or_null<FieldDecl>(Importer.Import(DIE->getField()));
if (!ToField && DIE->getField())
return nullptr;
@@ -6029,14 +6856,13 @@ Expr *ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
}
}
-
Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
return nullptr;
- NonTypeTemplateParmDecl *Param = cast_or_null<NonTypeTemplateParmDecl>(
+ auto *Param = cast_or_null<NonTypeTemplateParmDecl>(
Importer.Import(E->getParameter()));
if (!Param)
return nullptr;
@@ -6070,6 +6896,28 @@ Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue);
}
+Expr *ASTNodeImporter::VisitCXXTypeidExpr(CXXTypeidExpr *E) {
+ QualType ToType = Importer.Import(E->getType());
+ if (ToType.isNull())
+ return nullptr;
+
+ if (E->isTypeOperand()) {
+ TypeSourceInfo *TSI = Importer.Import(E->getTypeOperandSourceInfo());
+ if (!TSI)
+ return nullptr;
+
+ return new (Importer.getToContext())
+ CXXTypeidExpr(ToType, TSI, Importer.Import(E->getSourceRange()));
+ }
+
+ Expr *Op = Importer.Import(E->getExprOperand());
+ if (!Op)
+ return nullptr;
+
+ return new (Importer.getToContext())
+ CXXTypeidExpr(ToType, Op, Importer.Import(E->getSourceRange()));
+}
+
void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
@@ -6081,19 +6929,18 @@ void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager,
bool MinimalImport)
- : ToContext(ToContext), FromContext(FromContext),
- ToFileManager(ToFileManager), FromFileManager(FromFileManager),
- Minimal(MinimalImport), LastDiagFromFrom(false)
-{
+ : ToContext(ToContext), FromContext(FromContext),
+ ToFileManager(ToFileManager), FromFileManager(FromFileManager),
+ Minimal(MinimalImport) {
ImportedDecls[FromContext.getTranslationUnitDecl()]
= ToContext.getTranslationUnitDecl();
}
-ASTImporter::~ASTImporter() { }
+ASTImporter::~ASTImporter() = default;
QualType ASTImporter::Import(QualType FromT) {
if (FromT.isNull())
- return QualType();
+ return {};
const Type *fromTy = FromT.getTypePtr();
@@ -6129,10 +6976,17 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Import(FromTSI->getTypeLoc().getLocStart()));
}
+Attr *ASTImporter::Import(const Attr *FromAttr) {
+ Attr *ToAttr = FromAttr->clone(ToContext);
+ ToAttr->setRange(Import(FromAttr->getRange()));
+ return ToAttr;
+}
+
Decl *ASTImporter::GetAlreadyImportedOrNull(Decl *FromD) {
llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
if (Pos != ImportedDecls.end()) {
Decl *ToD = Pos->second;
+ // FIXME: move this call to ImportDeclParts().
ASTNodeImporter(*this).ImportDefinitionIfNeeded(FromD, ToD);
return ToD;
} else {
@@ -6146,44 +7000,22 @@ Decl *ASTImporter::Import(Decl *FromD) {
ASTNodeImporter Importer(*this);
- // Check whether we've already imported this declaration.
- llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
- if (Pos != ImportedDecls.end()) {
- Decl *ToD = Pos->second;
- Importer.ImportDefinitionIfNeeded(FromD, ToD);
+ // Check whether we've already imported this declaration.
+ Decl *ToD = GetAlreadyImportedOrNull(FromD);
+ if (ToD) {
+ // If FromD has some updated flags after last import, apply it
+ updateFlags(FromD, ToD);
return ToD;
}
-
- // Import the type
- Decl *ToD = Importer.Visit(FromD);
+
+ // Import the type.
+ ToD = Importer.Visit(FromD);
if (!ToD)
return nullptr;
- // Record the imported declaration.
- ImportedDecls[FromD] = ToD;
-
- if (TagDecl *FromTag = dyn_cast<TagDecl>(FromD)) {
- // Keep track of anonymous tags that have an associated typedef.
- if (FromTag->getTypedefNameForAnonDecl())
- AnonTagsWithPendingTypedefs.push_back(FromTag);
- } else if (TypedefNameDecl *FromTypedef = dyn_cast<TypedefNameDecl>(FromD)) {
- // When we've finished transforming a typedef, see whether it was the
- // typedef for an anonymous tag.
- for (SmallVectorImpl<TagDecl *>::iterator
- FromTag = AnonTagsWithPendingTypedefs.begin(),
- FromTagEnd = AnonTagsWithPendingTypedefs.end();
- FromTag != FromTagEnd; ++FromTag) {
- if ((*FromTag)->getTypedefNameForAnonDecl() == FromTypedef) {
- if (TagDecl *ToTag = cast_or_null<TagDecl>(Import(*FromTag))) {
- // We found the typedef for an anonymous tag; link them.
- ToTag->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToD));
- AnonTagsWithPendingTypedefs.erase(FromTag);
- break;
- }
- }
- }
- }
-
+ // Notify subclasses.
+ Imported(FromD, ToD);
+
return ToD;
}
@@ -6191,14 +7023,14 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
if (!FromDC)
return FromDC;
- DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
+ auto *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
if (!ToDC)
return nullptr;
// When we're using a record/enum/Objective-C class/protocol as a context, we
// need it to have a definition.
- if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
- RecordDecl *FromRecord = cast<RecordDecl>(FromDC);
+ if (auto *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
+ auto *FromRecord = cast<RecordDecl>(FromDC);
if (ToRecord->isCompleteDefinition()) {
// Do nothing.
} else if (FromRecord->isCompleteDefinition()) {
@@ -6207,8 +7039,8 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
} else {
CompleteDecl(ToRecord);
}
- } else if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
- EnumDecl *FromEnum = cast<EnumDecl>(FromDC);
+ } else if (auto *ToEnum = dyn_cast<EnumDecl>(ToDC)) {
+ auto *FromEnum = cast<EnumDecl>(FromDC);
if (ToEnum->isCompleteDefinition()) {
// Do nothing.
} else if (FromEnum->isCompleteDefinition()) {
@@ -6217,8 +7049,8 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
} else {
CompleteDecl(ToEnum);
}
- } else if (ObjCInterfaceDecl *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
- ObjCInterfaceDecl *FromClass = cast<ObjCInterfaceDecl>(FromDC);
+ } else if (auto *ToClass = dyn_cast<ObjCInterfaceDecl>(ToDC)) {
+ auto *FromClass = cast<ObjCInterfaceDecl>(FromDC);
if (ToClass->getDefinition()) {
// Do nothing.
} else if (ObjCInterfaceDecl *FromDef = FromClass->getDefinition()) {
@@ -6227,8 +7059,8 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
} else {
CompleteDecl(ToClass);
}
- } else if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
- ObjCProtocolDecl *FromProto = cast<ObjCProtocolDecl>(FromDC);
+ } else if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(ToDC)) {
+ auto *FromProto = cast<ObjCProtocolDecl>(FromDC);
if (ToProto->getDefinition()) {
// Do nothing.
} else if (ObjCProtocolDecl *FromDef = FromProto->getDefinition()) {
@@ -6283,14 +7115,14 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
return nullptr;
case NestedNameSpecifier::Namespace:
- if (NamespaceDecl *NS =
- cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
+ if (auto *NS =
+ cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NS);
}
return nullptr;
case NestedNameSpecifier::NamespaceAlias:
- if (NamespaceAliasDecl *NSAD =
+ if (auto *NSAD =
cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
}
@@ -6300,7 +7132,7 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
return NestedNameSpecifier::GlobalSpecifier(ToContext);
case NestedNameSpecifier::Super:
- if (CXXRecordDecl *RD =
+ if (auto *RD =
cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
}
@@ -6396,22 +7228,20 @@ NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
TemplateName ASTImporter::Import(TemplateName From) {
switch (From.getKind()) {
case TemplateName::Template:
- if (TemplateDecl *ToTemplate
- = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
+ if (auto *ToTemplate =
+ cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
return TemplateName(ToTemplate);
- return TemplateName();
+ return {};
case TemplateName::OverloadedTemplate: {
OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
UnresolvedSet<2> ToTemplates;
- for (OverloadedTemplateStorage::iterator I = FromStorage->begin(),
- E = FromStorage->end();
- I != E; ++I) {
- if (NamedDecl *To = cast_or_null<NamedDecl>(Import(*I)))
+ for (auto *I : *FromStorage) {
+ if (auto *To = cast_or_null<NamedDecl>(Import(I)))
ToTemplates.addDecl(To);
else
- return TemplateName();
+ return {};
}
return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
ToTemplates.end());
@@ -6421,22 +7251,22 @@ TemplateName ASTImporter::Import(TemplateName From) {
QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
if (!Qualifier)
- return TemplateName();
+ return {};
- if (TemplateDecl *ToTemplate
- = cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
+ if (auto *ToTemplate =
+ cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
return ToContext.getQualifiedTemplateName(Qualifier,
QTN->hasTemplateKeyword(),
ToTemplate);
-
- return TemplateName();
+
+ return {};
}
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = From.getAsDependentTemplateName();
NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
if (!Qualifier)
- return TemplateName();
+ return {};
if (DTN->isIdentifier()) {
return ToContext.getDependentTemplateName(Qualifier,
@@ -6449,13 +7279,14 @@ TemplateName ASTImporter::Import(TemplateName From) {
case TemplateName::SubstTemplateTemplateParm: {
SubstTemplateTemplateParmStorage *subst
= From.getAsSubstTemplateTemplateParm();
- TemplateTemplateParmDecl *param
- = cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
+ auto *param =
+ cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
if (!param)
- return TemplateName();
+ return {};
TemplateName replacement = Import(subst->getReplacement());
- if (replacement.isNull()) return TemplateName();
+ if (replacement.isNull())
+ return {};
return ToContext.getSubstTemplateTemplateParm(param, replacement);
}
@@ -6463,17 +7294,17 @@ TemplateName ASTImporter::Import(TemplateName From) {
case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage *SubstPack
= From.getAsSubstTemplateTemplateParmPack();
- TemplateTemplateParmDecl *Param
- = cast_or_null<TemplateTemplateParmDecl>(
- Import(SubstPack->getParameterPack()));
+ auto *Param =
+ cast_or_null<TemplateTemplateParmDecl>(
+ Import(SubstPack->getParameterPack()));
if (!Param)
- return TemplateName();
+ return {};
ASTNodeImporter Importer(*this);
TemplateArgument ArgPack
= Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
if (ArgPack.isNull())
- return TemplateName();
+ return {};
return ToContext.getSubstTemplateTemplateParmPack(Param, ArgPack);
}
@@ -6484,22 +7315,16 @@ TemplateName ASTImporter::Import(TemplateName From) {
SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
if (FromLoc.isInvalid())
- return SourceLocation();
+ return {};
SourceManager &FromSM = FromContext.getSourceManager();
-
- // For now, map everything down to its file location, so that we
- // don't have to import macro expansions.
- // FIXME: Import macro expansions!
- FromLoc = FromSM.getFileLoc(FromLoc);
+
std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
- SourceManager &ToSM = ToContext.getSourceManager();
FileID ToFileID = Import(Decomposed.first);
if (ToFileID.isInvalid())
- return SourceLocation();
- SourceLocation ret = ToSM.getLocForStartOfFile(ToFileID)
- .getLocWithOffset(Decomposed.second);
- return ret;
+ return {};
+ SourceManager &ToSM = ToContext.getSourceManager();
+ return ToSM.getComposedLoc(ToFileID, Decomposed.second);
}
SourceRange ASTImporter::Import(SourceRange FromRange) {
@@ -6507,44 +7332,58 @@ SourceRange ASTImporter::Import(SourceRange FromRange) {
}
FileID ASTImporter::Import(FileID FromID) {
- llvm::DenseMap<FileID, FileID>::iterator Pos
- = ImportedFileIDs.find(FromID);
+ llvm::DenseMap<FileID, FileID>::iterator Pos = ImportedFileIDs.find(FromID);
if (Pos != ImportedFileIDs.end())
return Pos->second;
-
+
SourceManager &FromSM = FromContext.getSourceManager();
SourceManager &ToSM = ToContext.getSourceManager();
const SrcMgr::SLocEntry &FromSLoc = FromSM.getSLocEntry(FromID);
- assert(FromSLoc.isFile() && "Cannot handle macro expansions yet");
-
- // Include location of this file.
- SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
-
- // Map the FileID for to the "to" source manager.
+
+ // Map the FromID to the "to" source manager.
FileID ToID;
- const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
- // FIXME: We probably want to use getVirtualFile(), so we don't hit the
- // disk again
- // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
- // than mmap the files several times.
- const FileEntry *Entry = ToFileManager.getFile(Cache->OrigEntry->getName());
- if (!Entry)
- return FileID();
- ToID = ToSM.createFileID(Entry, ToIncludeLoc,
- FromSLoc.getFile().getFileCharacteristic());
+ if (FromSLoc.isExpansion()) {
+ const SrcMgr::ExpansionInfo &FromEx = FromSLoc.getExpansion();
+ SourceLocation ToSpLoc = Import(FromEx.getSpellingLoc());
+ SourceLocation ToExLocS = Import(FromEx.getExpansionLocStart());
+ unsigned TokenLen = FromSM.getFileIDSize(FromID);
+ SourceLocation MLoc;
+ if (FromEx.isMacroArgExpansion()) {
+ MLoc = ToSM.createMacroArgExpansionLoc(ToSpLoc, ToExLocS, TokenLen);
+ } else {
+ SourceLocation ToExLocE = Import(FromEx.getExpansionLocEnd());
+ MLoc = ToSM.createExpansionLoc(ToSpLoc, ToExLocS, ToExLocE, TokenLen,
+ FromEx.isExpansionTokenRange());
+ }
+ ToID = ToSM.getFileID(MLoc);
} else {
- // FIXME: We want to re-use the existing MemoryBuffer!
- const llvm::MemoryBuffer *
- FromBuf = Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
- std::unique_ptr<llvm::MemoryBuffer> ToBuf
- = llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
- FromBuf->getBufferIdentifier());
- ToID = ToSM.createFileID(std::move(ToBuf),
- FromSLoc.getFile().getFileCharacteristic());
+ // Include location of this file.
+ SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
+
+ const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
+ if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
+ // FIXME: We probably want to use getVirtualFile(), so we don't hit the
+ // disk again
+ // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
+ // than mmap the files several times.
+ const FileEntry *Entry =
+ ToFileManager.getFile(Cache->OrigEntry->getName());
+ if (!Entry)
+ return {};
+ ToID = ToSM.createFileID(Entry, ToIncludeLoc,
+ FromSLoc.getFile().getFileCharacteristic());
+ } else {
+ // FIXME: We want to re-use the existing MemoryBuffer!
+ const llvm::MemoryBuffer *FromBuf =
+ Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
+ std::unique_ptr<llvm::MemoryBuffer> ToBuf =
+ llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
+ FromBuf->getBufferIdentifier());
+ ToID = ToSM.createFileID(std::move(ToBuf),
+ FromSLoc.getFile().getFileCharacteristic());
+ }
}
-
-
+
ImportedFileIDs[FromID] = ToID;
return ToID;
}
@@ -6565,8 +7404,7 @@ CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
From->isPackExpansion() ? Import(From->getEllipsisLoc())
: SourceLocation());
} else if (From->isMemberInitializer()) {
- FieldDecl *ToField =
- llvm::cast_or_null<FieldDecl>(Import(From->getMember()));
+ auto *ToField = cast_or_null<FieldDecl>(Import(From->getMember()));
if (!ToField && From->getMember())
return nullptr;
@@ -6574,7 +7412,7 @@ CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
ToContext, ToField, Import(From->getMemberLocation()),
Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()));
} else if (From->isIndirectMemberInitializer()) {
- IndirectFieldDecl *ToIField = llvm::cast_or_null<IndirectFieldDecl>(
+ auto *ToIField = cast_or_null<IndirectFieldDecl>(
Import(From->getIndirectMember()));
if (!ToIField && From->getIndirectMember())
return nullptr;
@@ -6595,7 +7433,6 @@ CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
}
}
-
CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec);
if (Pos != ImportedCXXBaseSpecifiers.end())
@@ -6616,10 +7453,10 @@ void ASTImporter::ImportDefinition(Decl *From) {
if (!To)
return;
- if (DeclContext *FromDC = cast<DeclContext>(From)) {
+ if (auto *FromDC = cast<DeclContext>(From)) {
ASTNodeImporter Importer(*this);
- if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(To)) {
+ if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
if (!ToRecord->getDefinition()) {
Importer.ImportDefinition(cast<RecordDecl>(FromDC), ToRecord,
ASTNodeImporter::IDK_Everything);
@@ -6627,7 +7464,7 @@ void ASTImporter::ImportDefinition(Decl *From) {
}
}
- if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) {
+ if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
if (!ToEnum->getDefinition()) {
Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
ASTNodeImporter::IDK_Everything);
@@ -6635,7 +7472,7 @@ void ASTImporter::ImportDefinition(Decl *From) {
}
}
- if (ObjCInterfaceDecl *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
+ if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
if (!ToIFace->getDefinition()) {
Importer.ImportDefinition(cast<ObjCInterfaceDecl>(FromDC), ToIFace,
ASTNodeImporter::IDK_Everything);
@@ -6643,7 +7480,7 @@ void ASTImporter::ImportDefinition(Decl *From) {
}
}
- if (ObjCProtocolDecl *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
+ if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
if (!ToProto->getDefinition()) {
Importer.ImportDefinition(cast<ObjCProtocolDecl>(FromDC), ToProto,
ASTNodeImporter::IDK_Everything);
@@ -6657,7 +7494,7 @@ void ASTImporter::ImportDefinition(Decl *From) {
DeclarationName ASTImporter::Import(DeclarationName FromName) {
if (!FromName)
- return DeclarationName();
+ return {};
switch (FromName.getNameKind()) {
case DeclarationName::Identifier:
@@ -6671,7 +7508,7 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
case DeclarationName::CXXConstructorName: {
QualType T = Import(FromName.getCXXNameType());
if (T.isNull())
- return DeclarationName();
+ return {};
return ToContext.DeclarationNames.getCXXConstructorName(
ToContext.getCanonicalType(T));
@@ -6680,24 +7517,24 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
case DeclarationName::CXXDestructorName: {
QualType T = Import(FromName.getCXXNameType());
if (T.isNull())
- return DeclarationName();
+ return {};
return ToContext.DeclarationNames.getCXXDestructorName(
ToContext.getCanonicalType(T));
}
case DeclarationName::CXXDeductionGuideName: {
- TemplateDecl *Template = cast_or_null<TemplateDecl>(
+ auto *Template = cast_or_null<TemplateDecl>(
Import(FromName.getCXXDeductionGuideTemplate()));
if (!Template)
- return DeclarationName();
+ return {};
return ToContext.DeclarationNames.getCXXDeductionGuideName(Template);
}
case DeclarationName::CXXConversionFunctionName: {
QualType T = Import(FromName.getCXXNameType());
if (T.isNull())
- return DeclarationName();
+ return {};
return ToContext.DeclarationNames.getCXXConversionFunctionName(
ToContext.getCanonicalType(T));
@@ -6733,7 +7570,7 @@ IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
Selector ASTImporter::Import(Selector FromSel) {
if (FromSel.isNull())
- return Selector();
+ return {};
SmallVector<IdentifierInfo *, 4> Idents;
Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
@@ -6767,36 +7604,31 @@ DiagnosticBuilder ASTImporter::FromDiag(SourceLocation Loc, unsigned DiagID) {
}
void ASTImporter::CompleteDecl (Decl *D) {
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+ if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
if (!ID->getDefinition())
ID->startDefinition();
}
- else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ else if (auto *PD = dyn_cast<ObjCProtocolDecl>(D)) {
if (!PD->getDefinition())
PD->startDefinition();
}
- else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ else if (auto *TD = dyn_cast<TagDecl>(D)) {
if (!TD->getDefinition() && !TD->isBeingDefined()) {
TD->startDefinition();
TD->setCompleteDefinition(true);
}
}
else {
- assert (0 && "CompleteDecl called on a Decl that can't be completed");
+ assert(0 && "CompleteDecl called on a Decl that can't be completed");
}
}
-Decl *ASTImporter::Imported(Decl *From, Decl *To) {
- if (From->hasAttrs()) {
- for (Attr *FromAttr : From->getAttrs())
- To->addAttr(FromAttr->clone(To->getASTContext()));
- }
- if (From->isUsed()) {
- To->setIsUsed();
- }
- if (From->isImplicit()) {
- To->setImplicit();
- }
+Decl *ASTImporter::MapImported(Decl *From, Decl *To) {
+ llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(From);
+ assert((Pos == ImportedDecls.end() || Pos->second == To) &&
+ "Try to import an already imported Decl");
+ if (Pos != ImportedDecls.end())
+ return Pos->second;
ImportedDecls[From] = To;
return To;
}
@@ -6809,6 +7641,7 @@ bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
return true;
StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
- false, Complain);
- return Ctx.IsStructurallyEquivalent(From, To);
+ getStructuralEquivalenceKind(*this), false,
+ Complain);
+ return Ctx.IsEquivalent(From, To);
}
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index 0df8e5653f3b..7853ab28810b 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -1,4 +1,4 @@
-//===--- ASTStructuralEquivalence.cpp - -------------------------*- C++ -*-===//
+//===- ASTStructuralEquivalence.cpp ---------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,20 +10,87 @@
// This file implement StructuralEquivalenceContext class and helper functions
// for layout matching.
//
+// The structural equivalence check could have been implemented as a parallel
+// BFS on a pair of graphs. That must have been the original approach at the
+// beginning.
+// Let's consider this simple BFS algorithm from the `s` source:
+// ```
+// void bfs(Graph G, int s)
+// {
+// Queue<Integer> queue = new Queue<Integer>();
+// marked[s] = true; // Mark the source
+// queue.enqueue(s); // and put it on the queue.
+// while (!q.isEmpty()) {
+// int v = queue.dequeue(); // Remove next vertex from the queue.
+// for (int w : G.adj(v))
+// if (!marked[w]) // For every unmarked adjacent vertex,
+// {
+// marked[w] = true;
+// queue.enqueue(w);
+// }
+// }
+// }
+// ```
+// Indeed, it has it's queue, which holds pairs of nodes, one from each graph,
+// this is the `DeclsToCheck` and it's pair is in `TentativeEquivalences`.
+// `TentativeEquivalences` also plays the role of the marking (`marked`)
+// functionality above, we use it to check whether we've already seen a pair of
+// nodes.
+//
+// We put in the elements into the queue only in the toplevel decl check
+// function:
+// ```
+// static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+// Decl *D1, Decl *D2);
+// ```
+// The `while` loop where we iterate over the children is implemented in
+// `Finish()`. And `Finish` is called only from the two **member** functions
+// which check the equivalency of two Decls or two Types. ASTImporter (and
+// other clients) call only these functions.
+//
+// The `static` implementation functions are called from `Finish`, these push
+// the children nodes to the queue via `static bool
+// IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Decl *D1,
+// Decl *D2)`. So far so good, this is almost like the BFS. However, if we
+// let a static implementation function to call `Finish` via another **member**
+// function that means we end up with two nested while loops each of them
+// working on the same queue. This is wrong and nobody can reason about it's
+// doing. Thus, static implementation functions must not call the **member**
+// functions.
+//
+// So, now `TentativeEquivalences` plays two roles. It is used to store the
+// second half of the decls which we want to compare, plus it plays a role in
+// closing the recursion. On a long term, we could refactor structural
+// equivalency to be more alike to the traditional BFS.
+//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTStructuralEquivalence.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/ASTImporter.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TypeVisitor.h"
-#include "clang/Basic/SourceManager.h"
-
-namespace {
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+#include <utility>
using namespace clang;
@@ -37,7 +104,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
/// Determine structural equivalence of two expressions.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
- Expr *E1, Expr *E2) {
+ const Expr *E1, const Expr *E2) {
if (!E1 || !E2)
return E1 == E2;
@@ -144,6 +211,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
IsStructurallyEquivalent(Context, TS1->getReplacement(),
TS2->getReplacement());
}
+
case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage
*P1 = N1.getAsSubstTemplateTemplateParmPack(),
@@ -169,10 +237,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
case TemplateArgument::Type:
- return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
+ return IsStructurallyEquivalent(Context, Arg1.getAsType(), Arg2.getAsType());
case TemplateArgument::Integral:
- if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
+ if (!IsStructurallyEquivalent(Context, Arg1.getIntegralType(),
Arg2.getIntegralType()))
return false;
@@ -180,7 +248,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Arg2.getAsIntegral());
case TemplateArgument::Declaration:
- return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
+ return IsStructurallyEquivalent(Context, Arg1.getAsDecl(), Arg2.getAsDecl());
case TemplateArgument::NullPtr:
return true; // FIXME: Is this correct?
@@ -235,6 +303,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (T1.isNull() || T2.isNull())
return T1.isNull() && T2.isNull();
+ QualType OrigT1 = T1;
+ QualType OrigT2 = T2;
+
if (!Context.StrictTypeSpelling) {
// We aren't being strict about token-to-token equivalence of types,
// so map down to the canonical type.
@@ -298,8 +369,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::LValueReference:
case Type::RValueReference: {
- const ReferenceType *Ref1 = cast<ReferenceType>(T1);
- const ReferenceType *Ref2 = cast<ReferenceType>(T2);
+ const auto *Ref1 = cast<ReferenceType>(T1);
+ const auto *Ref2 = cast<ReferenceType>(T2);
if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
return false;
if (Ref1->isInnerRef() != Ref2->isInnerRef())
@@ -311,8 +382,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::MemberPointer: {
- const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
- const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
+ const auto *MemPtr1 = cast<MemberPointerType>(T1);
+ const auto *MemPtr2 = cast<MemberPointerType>(T2);
if (!IsStructurallyEquivalent(Context, MemPtr1->getPointeeType(),
MemPtr2->getPointeeType()))
return false;
@@ -323,8 +394,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::ConstantArray: {
- const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
- const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
+ const auto *Array1 = cast<ConstantArrayType>(T1);
+ const auto *Array2 = cast<ConstantArrayType>(T2);
if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
return false;
@@ -340,8 +411,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
case Type::VariableArray: {
- const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
- const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
+ const auto *Array1 = cast<VariableArrayType>(T1);
+ const auto *Array2 = cast<VariableArrayType>(T2);
if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
Array2->getSizeExpr()))
return false;
@@ -353,8 +424,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::DependentSizedArray: {
- const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
- const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
+ const auto *Array1 = cast<DependentSizedArrayType>(T1);
+ const auto *Array2 = cast<DependentSizedArrayType>(T2);
if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
Array2->getSizeExpr()))
return false;
@@ -366,10 +437,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::DependentAddressSpace: {
- const DependentAddressSpaceType *DepAddressSpace1 =
- cast<DependentAddressSpaceType>(T1);
- const DependentAddressSpaceType *DepAddressSpace2 =
- cast<DependentAddressSpaceType>(T2);
+ const auto *DepAddressSpace1 = cast<DependentAddressSpaceType>(T1);
+ const auto *DepAddressSpace2 = cast<DependentAddressSpaceType>(T2);
if (!IsStructurallyEquivalent(Context, DepAddressSpace1->getAddrSpaceExpr(),
DepAddressSpace2->getAddrSpaceExpr()))
return false;
@@ -381,10 +450,22 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::DependentSizedExtVector: {
- const DependentSizedExtVectorType *Vec1 =
- cast<DependentSizedExtVectorType>(T1);
- const DependentSizedExtVectorType *Vec2 =
- cast<DependentSizedExtVectorType>(T2);
+ const auto *Vec1 = cast<DependentSizedExtVectorType>(T1);
+ const auto *Vec2 = cast<DependentSizedExtVectorType>(T2);
+ if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
+ Vec2->getSizeExpr()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
+ Vec2->getElementType()))
+ return false;
+ break;
+ }
+
+ case Type::DependentVector: {
+ const auto *Vec1 = cast<DependentVectorType>(T1);
+ const auto *Vec2 = cast<DependentVectorType>(T2);
+ if (Vec1->getVectorKind() != Vec2->getVectorKind())
+ return false;
if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
Vec2->getSizeExpr()))
return false;
@@ -396,8 +477,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::Vector:
case Type::ExtVector: {
- const VectorType *Vec1 = cast<VectorType>(T1);
- const VectorType *Vec2 = cast<VectorType>(T2);
+ const auto *Vec1 = cast<VectorType>(T1);
+ const auto *Vec2 = cast<VectorType>(T2);
if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
Vec2->getElementType()))
return false;
@@ -409,8 +490,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::FunctionProto: {
- const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
- const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
+ const auto *Proto1 = cast<FunctionProtoType>(T1);
+ const auto *Proto2 = cast<FunctionProtoType>(T2);
+
if (Proto1->getNumParams() != Proto2->getNumParams())
return false;
for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
@@ -420,31 +502,41 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
if (Proto1->isVariadic() != Proto2->isVariadic())
return false;
- if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
+
+ if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
return false;
- if (Proto1->getExceptionSpecType() == EST_Dynamic) {
- if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+
+ // Check exceptions, this information is lost in canonical type.
+ const auto *OrigProto1 =
+ cast<FunctionProtoType>(OrigT1.getDesugaredType(Context.FromCtx));
+ const auto *OrigProto2 =
+ cast<FunctionProtoType>(OrigT2.getDesugaredType(Context.ToCtx));
+ auto Spec1 = OrigProto1->getExceptionSpecType();
+ auto Spec2 = OrigProto2->getExceptionSpecType();
+
+ if (Spec1 != Spec2)
+ return false;
+ if (Spec1 == EST_Dynamic) {
+ if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
return false;
- for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
- if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
- Proto2->getExceptionType(I)))
+ for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
+ OrigProto2->getExceptionType(I)))
return false;
}
- } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
- if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
- Proto2->getNoexceptExpr()))
+ } else if (isComputedNoexcept(Spec1)) {
+ if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
+ OrigProto2->getNoexceptExpr()))
return false;
}
- if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
- return false;
// Fall through to check the bits common with FunctionNoProtoType.
LLVM_FALLTHROUGH;
}
case Type::FunctionNoProto: {
- const FunctionType *Function1 = cast<FunctionType>(T1);
- const FunctionType *Function2 = cast<FunctionType>(T2);
+ const auto *Function1 = cast<FunctionType>(T1);
+ const auto *Function2 = cast<FunctionType>(T2);
if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
Function2->getReturnType()))
return false;
@@ -458,7 +550,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
cast<UnresolvedUsingType>(T1)->getDecl(),
cast<UnresolvedUsingType>(T2)->getDecl()))
return false;
-
break;
case Type::Attributed:
@@ -501,7 +592,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::UnaryTransform:
if (!IsStructurallyEquivalent(
Context, cast<UnaryTransformType>(T1)->getUnderlyingType(),
- cast<UnaryTransformType>(T1)->getUnderlyingType()))
+ cast<UnaryTransformType>(T2)->getUnderlyingType()))
return false;
break;
@@ -519,8 +610,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
case Type::DeducedTemplateSpecialization: {
- auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
- auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
+ const auto *DT1 = cast<DeducedTemplateSpecializationType>(T1);
+ const auto *DT2 = cast<DeducedTemplateSpecializationType>(T2);
if (!IsStructurallyEquivalent(Context, DT1->getTemplateName(),
DT2->getTemplateName()))
return false;
@@ -538,8 +629,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
case Type::TemplateTypeParm: {
- const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
- const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
+ const auto *Parm1 = cast<TemplateTypeParmType>(T1);
+ const auto *Parm2 = cast<TemplateTypeParmType>(T2);
if (Parm1->getDepth() != Parm2->getDepth())
return false;
if (Parm1->getIndex() != Parm2->getIndex())
@@ -552,10 +643,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::SubstTemplateTypeParm: {
- const SubstTemplateTypeParmType *Subst1 =
- cast<SubstTemplateTypeParmType>(T1);
- const SubstTemplateTypeParmType *Subst2 =
- cast<SubstTemplateTypeParmType>(T2);
+ const auto *Subst1 = cast<SubstTemplateTypeParmType>(T1);
+ const auto *Subst2 = cast<SubstTemplateTypeParmType>(T2);
if (!IsStructurallyEquivalent(Context,
QualType(Subst1->getReplacedParameter(), 0),
QualType(Subst2->getReplacedParameter(), 0)))
@@ -567,10 +656,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::SubstTemplateTypeParmPack: {
- const SubstTemplateTypeParmPackType *Subst1 =
- cast<SubstTemplateTypeParmPackType>(T1);
- const SubstTemplateTypeParmPackType *Subst2 =
- cast<SubstTemplateTypeParmPackType>(T2);
+ const auto *Subst1 = cast<SubstTemplateTypeParmPackType>(T1);
+ const auto *Subst2 = cast<SubstTemplateTypeParmPackType>(T2);
if (!IsStructurallyEquivalent(Context,
QualType(Subst1->getReplacedParameter(), 0),
QualType(Subst2->getReplacedParameter(), 0)))
@@ -580,11 +667,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
}
+
case Type::TemplateSpecialization: {
- const TemplateSpecializationType *Spec1 =
- cast<TemplateSpecializationType>(T1);
- const TemplateSpecializationType *Spec2 =
- cast<TemplateSpecializationType>(T2);
+ const auto *Spec1 = cast<TemplateSpecializationType>(T1);
+ const auto *Spec2 = cast<TemplateSpecializationType>(T2);
if (!IsStructurallyEquivalent(Context, Spec1->getTemplateName(),
Spec2->getTemplateName()))
return false;
@@ -599,8 +685,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::Elaborated: {
- const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
- const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
+ const auto *Elab1 = cast<ElaboratedType>(T1);
+ const auto *Elab2 = cast<ElaboratedType>(T2);
// CHECKME: what if a keyword is ETK_None or ETK_typename ?
if (Elab1->getKeyword() != Elab2->getKeyword())
return false;
@@ -614,8 +700,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::InjectedClassName: {
- const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
- const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
+ const auto *Inj1 = cast<InjectedClassNameType>(T1);
+ const auto *Inj2 = cast<InjectedClassNameType>(T2);
if (!IsStructurallyEquivalent(Context,
Inj1->getInjectedSpecializationType(),
Inj2->getInjectedSpecializationType()))
@@ -624,8 +710,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::DependentName: {
- const DependentNameType *Typename1 = cast<DependentNameType>(T1);
- const DependentNameType *Typename2 = cast<DependentNameType>(T2);
+ const auto *Typename1 = cast<DependentNameType>(T1);
+ const auto *Typename2 = cast<DependentNameType>(T2);
if (!IsStructurallyEquivalent(Context, Typename1->getQualifier(),
Typename2->getQualifier()))
return false;
@@ -637,10 +723,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::DependentTemplateSpecialization: {
- const DependentTemplateSpecializationType *Spec1 =
- cast<DependentTemplateSpecializationType>(T1);
- const DependentTemplateSpecializationType *Spec2 =
- cast<DependentTemplateSpecializationType>(T2);
+ const auto *Spec1 = cast<DependentTemplateSpecializationType>(T1);
+ const auto *Spec2 = cast<DependentTemplateSpecializationType>(T2);
if (!IsStructurallyEquivalent(Context, Spec1->getQualifier(),
Spec2->getQualifier()))
return false;
@@ -665,8 +749,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
case Type::ObjCInterface: {
- const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
- const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
+ const auto *Iface1 = cast<ObjCInterfaceType>(T1);
+ const auto *Iface2 = cast<ObjCInterfaceType>(T2);
if (!IsStructurallyEquivalent(Context, Iface1->getDecl(),
Iface2->getDecl()))
return false;
@@ -674,8 +758,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::ObjCTypeParam: {
- const ObjCTypeParamType *Obj1 = cast<ObjCTypeParamType>(T1);
- const ObjCTypeParamType *Obj2 = cast<ObjCTypeParamType>(T2);
+ const auto *Obj1 = cast<ObjCTypeParamType>(T1);
+ const auto *Obj2 = cast<ObjCTypeParamType>(T2);
if (!IsStructurallyEquivalent(Context, Obj1->getDecl(), Obj2->getDecl()))
return false;
@@ -688,9 +772,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
break;
}
+
case Type::ObjCObject: {
- const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
- const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
+ const auto *Obj1 = cast<ObjCObjectType>(T1);
+ const auto *Obj2 = cast<ObjCObjectType>(T2);
if (!IsStructurallyEquivalent(Context, Obj1->getBaseType(),
Obj2->getBaseType()))
return false;
@@ -705,28 +790,25 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
case Type::ObjCObjectPointer: {
- const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
- const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
+ const auto *Ptr1 = cast<ObjCObjectPointerType>(T1);
+ const auto *Ptr2 = cast<ObjCObjectPointerType>(T2);
if (!IsStructurallyEquivalent(Context, Ptr1->getPointeeType(),
Ptr2->getPointeeType()))
return false;
break;
}
- case Type::Atomic: {
+ case Type::Atomic:
if (!IsStructurallyEquivalent(Context, cast<AtomicType>(T1)->getValueType(),
cast<AtomicType>(T2)->getValueType()))
return false;
break;
- }
- case Type::Pipe: {
+ case Type::Pipe:
if (!IsStructurallyEquivalent(Context, cast<PipeType>(T1)->getElementType(),
cast<PipeType>(T2)->getElementType()))
return false;
break;
- }
-
} // end switch
return true;
@@ -735,7 +817,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
/// Determine structural equivalence of two fields.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
FieldDecl *Field1, FieldDecl *Field2) {
- RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
+ const auto *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
// For anonymous structs/unions, match up the anonymous struct/union type
// declarations directly, so that we don't go off searching for anonymous
@@ -829,6 +911,56 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
}
+/// Determine structural equivalence of two methodss.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ CXXMethodDecl *Method1,
+ CXXMethodDecl *Method2) {
+ bool PropertiesEqual =
+ Method1->getDeclKind() == Method2->getDeclKind() &&
+ Method1->getRefQualifier() == Method2->getRefQualifier() &&
+ Method1->getAccess() == Method2->getAccess() &&
+ Method1->getOverloadedOperator() == Method2->getOverloadedOperator() &&
+ Method1->isStatic() == Method2->isStatic() &&
+ Method1->isConst() == Method2->isConst() &&
+ Method1->isVolatile() == Method2->isVolatile() &&
+ Method1->isVirtual() == Method2->isVirtual() &&
+ Method1->isPure() == Method2->isPure() &&
+ Method1->isDefaulted() == Method2->isDefaulted() &&
+ Method1->isDeleted() == Method2->isDeleted();
+ if (!PropertiesEqual)
+ return false;
+ // FIXME: Check for 'final'.
+
+ if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
+ auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
+ if (Constructor1->isExplicit() != Constructor2->isExplicit())
+ return false;
+ }
+
+ if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
+ auto *Conversion2 = cast<CXXConversionDecl>(Method2);
+ if (Conversion1->isExplicit() != Conversion2->isExplicit())
+ return false;
+ if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(),
+ Conversion2->getConversionType()))
+ return false;
+ }
+
+ const IdentifierInfo *Name1 = Method1->getIdentifier();
+ const IdentifierInfo *Name2 = Method2->getIdentifier();
+ if (!::IsStructurallyEquivalent(Name1, Name2)) {
+ return false;
+ // TODO: Names do not match, add warning like at check for FieldDecl.
+ }
+
+ // Check the prototypes.
+ if (!::IsStructurallyEquivalent(Context,
+ Method1->getType(), Method2->getType()))
+ return false;
+
+ return true;
+}
+
/// Determine structural equivalence of two records.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
RecordDecl *D1, RecordDecl *D2) {
@@ -845,7 +977,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
}
- if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
+ if (!D1->getDeclName() && !D2->getDeclName()) {
// If both anonymous structs/unions are in a record context, make sure
// they occur in the same location in the context records.
if (Optional<unsigned> Index1 =
@@ -861,10 +993,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// If both declarations are class template specializations, we know
// the ODR applies, so check the template and template arguments.
- ClassTemplateSpecializationDecl *Spec1 =
- dyn_cast<ClassTemplateSpecializationDecl>(D1);
- ClassTemplateSpecializationDecl *Spec2 =
- dyn_cast<ClassTemplateSpecializationDecl>(D2);
+ const auto *Spec1 = dyn_cast<ClassTemplateSpecializationDecl>(D1);
+ const auto *Spec2 = dyn_cast<ClassTemplateSpecializationDecl>(D2);
if (Spec1 && Spec2) {
// Check that the specialized templates are the same.
if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
@@ -892,8 +1022,17 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!D1 || !D2)
return true;
- if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
- if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
+ // If any of the records has external storage and we do a minimal check (or
+ // AST import) we assmue they are equivalent. (If we didn't have this
+ // assumption then `RecordDecl::LoadFieldsFromExternalStorage` could trigger
+ // another AST import which in turn would call the structural equivalency
+ // check again and finally we'd have an improper result.)
+ if (Context.EqKind == StructuralEquivalenceKind::Minimal)
+ if (D1->hasExternalLexicalStorage() || D2->hasExternalLexicalStorage())
+ return true;
+
+ if (auto *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
+ if (auto *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
if (D1CXX->hasExternalLexicalStorage() &&
!D1CXX->isCompleteDefinition()) {
D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
@@ -944,6 +1083,44 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
}
}
+
+ // Check the friends for consistency.
+ CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
+ Friend2End = D2CXX->friend_end();
+ for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
+ Friend1End = D1CXX->friend_end();
+ Friend1 != Friend1End; ++Friend1, ++Friend2) {
+ if (Friend2 == Friend2End) {
+ if (Context.Complain) {
+ Context.Diag2(D2->getLocation(),
+ diag::warn_odr_tag_type_inconsistent)
+ << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
+ Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
+ }
+ return false;
+ }
+
+ if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
+ if (Context.Complain) {
+ Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
+ Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
+ }
+ return false;
+ }
+ }
+
+ if (Friend2 != Friend2End) {
+ if (Context.Complain) {
+ Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ << Context.ToCtx.getTypeDeclType(D2);
+ Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
+ Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
+ }
+ return false;
+ }
} else if (D1CXX->getNumBases() > 0) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
@@ -1081,11 +1258,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
}
- if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
- Params2->getParam(I))) {
-
+ if (!IsStructurallyEquivalent(Context, Params1->getParam(I),
+ Params2->getParam(I)))
return false;
- }
}
return true;
@@ -1121,7 +1296,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
// Check types.
- if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
+ if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
diag::err_odr_non_type_parameter_type_inconsistent)
@@ -1153,17 +1328,64 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
D2->getTemplateParameters());
}
+static bool IsTemplateDeclCommonStructurallyEquivalent(
+ StructuralEquivalenceContext &Ctx, TemplateDecl *D1, TemplateDecl *D2) {
+ if (!IsStructurallyEquivalent(D1->getIdentifier(), D2->getIdentifier()))
+ return false;
+ if (!D1->getIdentifier()) // Special name
+ if (D1->getNameAsString() != D2->getNameAsString())
+ return false;
+ return IsStructurallyEquivalent(Ctx, D1->getTemplateParameters(),
+ D2->getTemplateParameters());
+}
+
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
ClassTemplateDecl *D1,
ClassTemplateDecl *D2) {
// Check template parameters.
- if (!IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
- D2->getTemplateParameters()))
+ if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
+ return false;
+
+ // Check the templated declaration.
+ return IsStructurallyEquivalent(Context, D1->getTemplatedDecl(),
+ D2->getTemplatedDecl());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FunctionTemplateDecl *D1,
+ FunctionTemplateDecl *D2) {
+ // Check template parameters.
+ if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
return false;
// Check the templated declaration.
- return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(),
- D2->getTemplatedDecl());
+ return IsStructurallyEquivalent(Context, D1->getTemplatedDecl()->getType(),
+ D2->getTemplatedDecl()->getType());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FriendDecl *D1, FriendDecl *D2) {
+ if ((D1->getFriendType() && D2->getFriendDecl()) ||
+ (D1->getFriendDecl() && D2->getFriendType())) {
+ return false;
+ }
+ if (D1->getFriendType() && D2->getFriendType())
+ return IsStructurallyEquivalent(Context,
+ D1->getFriendType()->getType(),
+ D2->getFriendType()->getType());
+ if (D1->getFriendDecl() && D2->getFriendDecl())
+ return IsStructurallyEquivalent(Context, D1->getFriendDecl(),
+ D2->getFriendDecl());
+ return false;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FunctionDecl *D1, FunctionDecl *D2) {
+ // FIXME: Consider checking for function attributes as well.
+ if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType()))
+ return false;
+
+ return true;
}
/// Determine structural equivalence of two declarations.
@@ -1187,9 +1409,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
return true;
}
-} // namespace
-
-namespace clang {
DiagnosticBuilder StructuralEquivalenceContext::Diag1(SourceLocation Loc,
unsigned DiagID) {
@@ -1214,7 +1433,7 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
ASTContext &Context = Anon->getASTContext();
QualType AnonTy = Context.getRecordType(Anon);
- RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
+ const auto *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
if (!Owner)
return None;
@@ -1234,6 +1453,10 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
// If the field looks like this:
// struct { ... } A;
QualType FieldType = F->getType();
+ // In case of nested structs.
+ while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
+ FieldType = ElabType->getNamedType();
+
if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
const RecordDecl *RecDecl = RecType->getDecl();
if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
@@ -1248,16 +1471,26 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
return Index;
}
-bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
- Decl *D2) {
+bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {
+
+ // Ensure that the implementation functions (all static functions in this TU)
+ // never call the public ASTStructuralEquivalence::IsEquivalent() functions,
+ // because that will wreak havoc the internal state (DeclsToCheck and
+ // TentativeEquivalences members) and can cause faulty behaviour. For
+ // instance, some leaf declarations can be stated and cached as inequivalent
+ // as a side effect of one inequivalent element in the DeclsToCheck list.
+ assert(DeclsToCheck.empty());
+ assert(TentativeEquivalences.empty());
+
if (!::IsStructurallyEquivalent(*this, D1, D2))
return false;
return !Finish();
}
-bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
- QualType T2) {
+bool StructuralEquivalenceContext::IsEquivalent(QualType T1, QualType T2) {
+ assert(DeclsToCheck.empty());
+ assert(TentativeEquivalences.empty());
if (!::IsStructurallyEquivalent(*this, T1, T2))
return false;
@@ -1277,8 +1510,8 @@ bool StructuralEquivalenceContext::Finish() {
// FIXME: Switch on all declaration kinds. For now, we're just going to
// check the obvious ones.
- if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
- if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
+ if (auto *Record1 = dyn_cast<RecordDecl>(D1)) {
+ if (auto *Record2 = dyn_cast<RecordDecl>(D2)) {
// Check for equivalent structure names.
IdentifierInfo *Name1 = Record1->getIdentifier();
if (!Name1 && Record1->getTypedefNameForAnonDecl())
@@ -1293,8 +1526,8 @@ bool StructuralEquivalenceContext::Finish() {
// Record/non-record mismatch.
Equivalent = false;
}
- } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
- if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
+ } else if (auto *Enum1 = dyn_cast<EnumDecl>(D1)) {
+ if (auto *Enum2 = dyn_cast<EnumDecl>(D2)) {
// Check for equivalent enum names.
IdentifierInfo *Name1 = Enum1->getIdentifier();
if (!Name1 && Enum1->getTypedefNameForAnonDecl())
@@ -1309,8 +1542,8 @@ bool StructuralEquivalenceContext::Finish() {
// Enum/non-enum mismatch
Equivalent = false;
}
- } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
- if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
+ } else if (const auto *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
+ if (const auto *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
Typedef2->getIdentifier()) ||
!::IsStructurallyEquivalent(*this, Typedef1->getUnderlyingType(),
@@ -1320,46 +1553,75 @@ bool StructuralEquivalenceContext::Finish() {
// Typedef/non-typedef mismatch.
Equivalent = false;
}
- } else if (ClassTemplateDecl *ClassTemplate1 =
- dyn_cast<ClassTemplateDecl>(D1)) {
- if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
- if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
- ClassTemplate2->getIdentifier()) ||
- !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
+ } else if (auto *ClassTemplate1 = dyn_cast<ClassTemplateDecl>(D1)) {
+ if (auto *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, ClassTemplate1,
+ ClassTemplate2))
+ Equivalent = false;
+ } else {
+ // Class template/non-class-template mismatch.
+ Equivalent = false;
+ }
+ } else if (auto *FunctionTemplate1 = dyn_cast<FunctionTemplateDecl>(D1)) {
+ if (auto *FunctionTemplate2 = dyn_cast<FunctionTemplateDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, FunctionTemplate1,
+ FunctionTemplate2))
Equivalent = false;
} else {
// Class template/non-class-template mismatch.
Equivalent = false;
}
- } else if (TemplateTypeParmDecl *TTP1 =
- dyn_cast<TemplateTypeParmDecl>(D1)) {
- if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
+ } else if (auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
+ if (auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
Equivalent = false;
} else {
// Kind mismatch.
Equivalent = false;
}
- } else if (NonTypeTemplateParmDecl *NTTP1 =
- dyn_cast<NonTypeTemplateParmDecl>(D1)) {
- if (NonTypeTemplateParmDecl *NTTP2 =
- dyn_cast<NonTypeTemplateParmDecl>(D2)) {
+ } else if (auto *NTTP1 = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
+ if (auto *NTTP2 = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
Equivalent = false;
} else {
// Kind mismatch.
Equivalent = false;
}
- } else if (TemplateTemplateParmDecl *TTP1 =
- dyn_cast<TemplateTemplateParmDecl>(D1)) {
- if (TemplateTemplateParmDecl *TTP2 =
- dyn_cast<TemplateTemplateParmDecl>(D2)) {
+ } else if (auto *TTP1 = dyn_cast<TemplateTemplateParmDecl>(D1)) {
+ if (auto *TTP2 = dyn_cast<TemplateTemplateParmDecl>(D2)) {
if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
Equivalent = false;
} else {
// Kind mismatch.
Equivalent = false;
}
+ } else if (auto *MD1 = dyn_cast<CXXMethodDecl>(D1)) {
+ if (auto *MD2 = dyn_cast<CXXMethodDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, MD1, MD2))
+ Equivalent = false;
+ } else {
+ // Kind mismatch.
+ Equivalent = false;
+ }
+ } else if (FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
+ if (FunctionDecl *FD2 = dyn_cast<FunctionDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(FD1->getIdentifier(),
+ FD2->getIdentifier()))
+ Equivalent = false;
+ if (!::IsStructurallyEquivalent(*this, FD1, FD2))
+ Equivalent = false;
+ } else {
+ // Kind mismatch.
+ Equivalent = false;
+ }
+ } else if (FriendDecl *FrD1 = dyn_cast<FriendDecl>(D1)) {
+ if (FriendDecl *FrD2 = dyn_cast<FriendDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, FrD1, FrD2))
+ Equivalent = false;
+ } else {
+ // Kind mismatch.
+ Equivalent = false;
+ }
}
if (!Equivalent) {
@@ -1374,4 +1636,3 @@ bool StructuralEquivalenceContext::Finish() {
return false;
}
-} // namespace clang
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index a6f1027856c7..4f868a3af59e 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
+ ComparisonCategories.cpp
DataCollection.cpp
Decl.cpp
DeclarationName.cpp
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 24e96ba38015..2825329775ed 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -34,13 +34,13 @@
using namespace clang;
-/// \brief Computes the set of declarations referenced by these base
+/// Computes the set of declarations referenced by these base
/// paths.
void CXXBasePaths::ComputeDeclsFound() {
assert(NumDeclsFound == 0 && !DeclsFound &&
"Already computed the set of declarations");
- llvm::SetVector<NamedDecl *, SmallVector<NamedDecl *, 8>> Decls;
+ llvm::SmallSetVector<NamedDecl *, 8> Decls;
for (paths_iterator Path = begin(), PathEnd = end(); Path != PathEnd; ++Path)
Decls.insert(Path->Decls.front());
@@ -63,8 +63,8 @@ CXXBasePaths::decl_range CXXBasePaths::found_decls() {
/// an unqualified, canonical class type.
bool CXXBasePaths::isAmbiguous(CanQualType BaseType) {
BaseType = BaseType.getUnqualifiedType();
- std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
- return Subobjects.second + (Subobjects.first? 1 : 0) > 1;
+ IsVirtBaseAndNumberNonVirtBases Subobjects = ClassSubobjects[BaseType];
+ return Subobjects.NumberOfNonVirtBases + (Subobjects.IsVirtBase ? 1 : 0) > 1;
}
/// clear - Clear out all prior path information.
@@ -76,7 +76,7 @@ void CXXBasePaths::clear() {
DetectedVirtual = nullptr;
}
-/// @brief Swaps the contents of this CXXBasePaths structure with the
+/// Swaps the contents of this CXXBasePaths structure with the
/// contents of Other.
void CXXBasePaths::swap(CXXBasePaths &Other) {
std::swap(Origin, Other.Origin);
@@ -217,21 +217,21 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// Determine whether we need to visit this base class at all,
// updating the count of subobjects appropriately.
- std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
+ IsVirtBaseAndNumberNonVirtBases &Subobjects = ClassSubobjects[BaseType];
bool VisitBase = true;
bool SetVirtual = false;
if (BaseSpec.isVirtual()) {
- VisitBase = !Subobjects.first;
- Subobjects.first = true;
+ VisitBase = !Subobjects.IsVirtBase;
+ Subobjects.IsVirtBase = true;
if (isDetectingVirtual() && DetectedVirtual == nullptr) {
// If this is the first virtual we find, remember it. If it turns out
// there is no base path here, we'll reset it later.
DetectedVirtual = BaseType->getAs<RecordType>();
SetVirtual = true;
}
- } else
- ++Subobjects.second;
-
+ } else {
+ ++Subobjects.NumberOfNonVirtBases;
+ }
if (isRecordingPaths()) {
// Add this base specifier to the current path.
CXXBasePathElement Element;
@@ -240,7 +240,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
if (BaseSpec.isVirtual())
Element.SubobjectNumber = 0;
else
- Element.SubobjectNumber = Subobjects.second;
+ Element.SubobjectNumber = Subobjects.NumberOfNonVirtBases;
ScratchPath.push_back(Element);
// Calculate the "top-down" access to this base class.
@@ -567,11 +567,11 @@ void OverridingMethods::replaceAll(UniqueVirtualMethod Overriding) {
namespace {
class FinalOverriderCollector {
- /// \brief The number of subobjects of a given class type that
+ /// 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.
+ /// Overriders for each virtual base subobject.
llvm::DenseMap<const CXXRecordDecl *, CXXFinalOverriderMap *> VirtualOverriders;
CXXFinalOverriderMap FinalOverriders;
@@ -637,8 +637,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
OMEnd = BaseOverriders->end();
OM != OMEnd;
++OM) {
- const CXXMethodDecl *CanonOM
- = cast<CXXMethodDecl>(OM->first->getCanonicalDecl());
+ const CXXMethodDecl *CanonOM = OM->first->getCanonicalDecl();
Overriders[CanonOM].add(OM->second);
}
}
@@ -649,7 +648,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
if (!M->isVirtual())
continue;
- CXXMethodDecl *CanonM = cast<CXXMethodDecl>(M->getCanonicalDecl());
+ CXXMethodDecl *CanonM = M->getCanonicalDecl();
using OverriddenMethodsRange =
llvm::iterator_range<CXXMethodDecl::method_iterator>;
OverriddenMethodsRange OverriddenMethods = CanonM->overridden_methods();
diff --git a/lib/AST/CommentBriefParser.cpp b/lib/AST/CommentBriefParser.cpp
index eecea8fc11df..5ec7586a475d 100644
--- a/lib/AST/CommentBriefParser.cpp
+++ b/lib/AST/CommentBriefParser.cpp
@@ -122,8 +122,8 @@ std::string BriefParser::Parse() {
if (Tok.is(tok::newline)) {
ConsumeToken();
// We found a paragraph end. This ends the brief description if
- // \\brief command or its equivalent was explicitly used.
- // Stop scanning text because an explicit \\brief paragraph is the
+ // \command or its equivalent was explicitly used.
+ // Stop scanning text because an explicit \paragraph is the
// preffered one.
if (InBrief)
break;
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index 65d0f56f09ab..6ff4d45a9572 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -294,6 +294,39 @@ void Lexer::lexCommentText(Token &T) {
assert(CommentState == LCS_InsideBCPLComment ||
CommentState == LCS_InsideCComment);
+ // Handles lexing non-command text, i.e. text and newline.
+ auto HandleNonCommandToken = [&]() -> void {
+ assert(State == LS_Normal);
+
+ const char *TokenPtr = BufferPtr;
+ assert(TokenPtr < CommentEnd);
+ switch (*TokenPtr) {
+ case '\n':
+ case '\r':
+ TokenPtr = skipNewline(TokenPtr, CommentEnd);
+ formTokenWithChars(T, TokenPtr, tok::newline);
+
+ if (CommentState == LCS_InsideCComment)
+ skipLineStartingDecorations();
+ return;
+
+ default: {
+ StringRef TokStartSymbols = ParseCommands ? "\n\r\\@&<" : "\n\r";
+ size_t End = StringRef(TokenPtr, CommentEnd - TokenPtr)
+ .find_first_of(TokStartSymbols);
+ if (End != StringRef::npos)
+ TokenPtr += End;
+ else
+ TokenPtr = CommentEnd;
+ formTextToken(T, TokenPtr);
+ return;
+ }
+ }
+ };
+
+ if (!ParseCommands)
+ return HandleNonCommandToken();
+
switch (State) {
case LS_Normal:
break;
@@ -315,136 +348,116 @@ void Lexer::lexCommentText(Token &T) {
}
assert(State == LS_Normal);
-
const char *TokenPtr = BufferPtr;
assert(TokenPtr < CommentEnd);
- while (TokenPtr != CommentEnd) {
- switch(*TokenPtr) {
- case '\\':
- case '@': {
- // Commands that start with a backslash and commands that start with
- // 'at' have equivalent semantics. But we keep information about the
- // exact syntax in AST for comments.
- tok::TokenKind CommandKind =
- (*TokenPtr == '@') ? tok::at_command : tok::backslash_command;
+ switch(*TokenPtr) {
+ case '\\':
+ case '@': {
+ // Commands that start with a backslash and commands that start with
+ // 'at' have equivalent semantics. But we keep information about the
+ // exact syntax in AST for comments.
+ tok::TokenKind CommandKind =
+ (*TokenPtr == '@') ? tok::at_command : tok::backslash_command;
+ TokenPtr++;
+ if (TokenPtr == CommentEnd) {
+ formTextToken(T, TokenPtr);
+ return;
+ }
+ char C = *TokenPtr;
+ switch (C) {
+ default:
+ break;
+
+ case '\\': case '@': case '&': case '$':
+ case '#': case '<': case '>': case '%':
+ case '\"': case '.': case ':':
+ // This is one of \\ \@ \& \$ etc escape sequences.
TokenPtr++;
- if (TokenPtr == CommentEnd) {
- formTextToken(T, TokenPtr);
- return;
- }
- char C = *TokenPtr;
- switch (C) {
- default:
- break;
-
- case '\\': case '@': case '&': case '$':
- case '#': case '<': case '>': case '%':
- case '\"': case '.': case ':':
- // This is one of \\ \@ \& \$ etc escape sequences.
+ if (C == ':' && TokenPtr != CommentEnd && *TokenPtr == ':') {
+ // This is the \:: escape sequence.
TokenPtr++;
- if (C == ':' && TokenPtr != CommentEnd && *TokenPtr == ':') {
- // This is the \:: escape sequence.
- TokenPtr++;
- }
- StringRef UnescapedText(BufferPtr + 1, TokenPtr - (BufferPtr + 1));
- formTokenWithChars(T, TokenPtr, tok::text);
- T.setText(UnescapedText);
- return;
}
+ StringRef UnescapedText(BufferPtr + 1, TokenPtr - (BufferPtr + 1));
+ formTokenWithChars(T, TokenPtr, tok::text);
+ T.setText(UnescapedText);
+ return;
+ }
- // Don't make zero-length commands.
- if (!isCommandNameStartCharacter(*TokenPtr)) {
- formTextToken(T, TokenPtr);
- return;
- }
+ // Don't make zero-length commands.
+ if (!isCommandNameStartCharacter(*TokenPtr)) {
+ formTextToken(T, TokenPtr);
+ return;
+ }
- TokenPtr = skipCommandName(TokenPtr, CommentEnd);
- unsigned Length = TokenPtr - (BufferPtr + 1);
-
- // Hardcoded support for lexing LaTeX formula commands
- // \f$ \f[ \f] \f{ \f} as a single command.
- if (Length == 1 && TokenPtr[-1] == 'f' && TokenPtr != CommentEnd) {
- C = *TokenPtr;
- if (C == '$' || C == '[' || C == ']' || C == '{' || C == '}') {
- TokenPtr++;
- Length++;
- }
- }
+ TokenPtr = skipCommandName(TokenPtr, CommentEnd);
+ unsigned Length = TokenPtr - (BufferPtr + 1);
- StringRef CommandName(BufferPtr + 1, Length);
-
- const CommandInfo *Info = Traits.getCommandInfoOrNULL(CommandName);
- if (!Info) {
- if ((Info = Traits.getTypoCorrectCommandInfo(CommandName))) {
- StringRef CorrectedName = Info->Name;
- SourceLocation Loc = getSourceLocation(BufferPtr);
- SourceLocation EndLoc = getSourceLocation(TokenPtr);
- SourceRange FullRange = SourceRange(Loc, EndLoc);
- SourceRange CommandRange(Loc.getLocWithOffset(1), EndLoc);
- Diag(Loc, diag::warn_correct_comment_command_name)
- << FullRange << CommandName << CorrectedName
- << FixItHint::CreateReplacement(CommandRange, CorrectedName);
- } else {
- formTokenWithChars(T, TokenPtr, tok::unknown_command);
- T.setUnknownCommandName(CommandName);
- Diag(T.getLocation(), diag::warn_unknown_comment_command_name)
- << SourceRange(T.getLocation(), T.getEndLocation());
- return;
- }
- }
- if (Info->IsVerbatimBlockCommand) {
- setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, Info);
- return;
- }
- if (Info->IsVerbatimLineCommand) {
- setupAndLexVerbatimLine(T, TokenPtr, Info);
- return;
+ // Hardcoded support for lexing LaTeX formula commands
+ // \f$ \f[ \f] \f{ \f} as a single command.
+ if (Length == 1 && TokenPtr[-1] == 'f' && TokenPtr != CommentEnd) {
+ C = *TokenPtr;
+ if (C == '$' || C == '[' || C == ']' || C == '{' || C == '}') {
+ TokenPtr++;
+ Length++;
}
- formTokenWithChars(T, TokenPtr, CommandKind);
- T.setCommandID(Info->getID());
- return;
}
- case '&':
- lexHTMLCharacterReference(T);
- return;
-
- case '<': {
- TokenPtr++;
- if (TokenPtr == CommentEnd) {
- formTextToken(T, TokenPtr);
+ StringRef CommandName(BufferPtr + 1, Length);
+
+ const CommandInfo *Info = Traits.getCommandInfoOrNULL(CommandName);
+ if (!Info) {
+ if ((Info = Traits.getTypoCorrectCommandInfo(CommandName))) {
+ StringRef CorrectedName = Info->Name;
+ SourceLocation Loc = getSourceLocation(BufferPtr);
+ SourceLocation EndLoc = getSourceLocation(TokenPtr);
+ SourceRange FullRange = SourceRange(Loc, EndLoc);
+ SourceRange CommandRange(Loc.getLocWithOffset(1), EndLoc);
+ Diag(Loc, diag::warn_correct_comment_command_name)
+ << FullRange << CommandName << CorrectedName
+ << FixItHint::CreateReplacement(CommandRange, CorrectedName);
+ } else {
+ formTokenWithChars(T, TokenPtr, tok::unknown_command);
+ T.setUnknownCommandName(CommandName);
+ Diag(T.getLocation(), diag::warn_unknown_comment_command_name)
+ << SourceRange(T.getLocation(), T.getEndLocation());
return;
}
- const char C = *TokenPtr;
- if (isHTMLIdentifierStartingCharacter(C))
- setupAndLexHTMLStartTag(T);
- else if (C == '/')
- setupAndLexHTMLEndTag(T);
- else
- formTextToken(T, TokenPtr);
+ }
+ if (Info->IsVerbatimBlockCommand) {
+ setupAndLexVerbatimBlock(T, TokenPtr, *BufferPtr, Info);
return;
}
-
- case '\n':
- case '\r':
- TokenPtr = skipNewline(TokenPtr, CommentEnd);
- formTokenWithChars(T, TokenPtr, tok::newline);
-
- if (CommentState == LCS_InsideCComment)
- skipLineStartingDecorations();
+ if (Info->IsVerbatimLineCommand) {
+ setupAndLexVerbatimLine(T, TokenPtr, Info);
return;
+ }
+ formTokenWithChars(T, TokenPtr, CommandKind);
+ T.setCommandID(Info->getID());
+ return;
+ }
- default: {
- size_t End = StringRef(TokenPtr, CommentEnd - TokenPtr).
- find_first_of("\n\r\\@&<");
- if (End != StringRef::npos)
- TokenPtr += End;
- else
- TokenPtr = CommentEnd;
+ case '&':
+ lexHTMLCharacterReference(T);
+ return;
+
+ case '<': {
+ TokenPtr++;
+ if (TokenPtr == CommentEnd) {
formTextToken(T, TokenPtr);
return;
}
+ const char C = *TokenPtr;
+ if (isHTMLIdentifierStartingCharacter(C))
+ setupAndLexHTMLStartTag(T);
+ else if (C == '/')
+ setupAndLexHTMLEndTag(T);
+ else
+ formTextToken(T, TokenPtr);
+ return;
}
+
+ default:
+ return HandleNonCommandToken();
}
}
@@ -727,14 +740,13 @@ void Lexer::lexHTMLEndTag(Token &T) {
}
Lexer::Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
- const CommandTraits &Traits,
- SourceLocation FileLoc,
- const char *BufferStart, const char *BufferEnd):
- Allocator(Allocator), Diags(Diags), Traits(Traits),
- BufferStart(BufferStart), BufferEnd(BufferEnd),
- FileLoc(FileLoc), BufferPtr(BufferStart),
- CommentState(LCS_BeforeComment), State(LS_Normal) {
-}
+ const CommandTraits &Traits, SourceLocation FileLoc,
+ const char *BufferStart, const char *BufferEnd,
+ bool ParseCommands)
+ : Allocator(Allocator), Diags(Diags), Traits(Traits),
+ BufferStart(BufferStart), BufferEnd(BufferEnd), FileLoc(FileLoc),
+ BufferPtr(BufferStart), CommentState(LCS_BeforeComment), State(LS_Normal),
+ ParseCommands(ParseCommands) {}
void Lexer::lex(Token &T) {
again:
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 6c2019e1a72b..4bc98bf10765 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -215,7 +215,7 @@ void Sema::checkContainerDecl(const BlockCommandComment *Comment) {
<< Comment->getSourceRange();
}
-/// \brief Turn a string into the corresponding PassDirection or -1 if it's not
+/// Turn a string into the corresponding PassDirection or -1 if it's not
/// valid.
static int getParamPassDirection(StringRef Arg) {
return llvm::StringSwitch<int>(Arg)
diff --git a/lib/AST/ComparisonCategories.cpp b/lib/AST/ComparisonCategories.cpp
new file mode 100644
index 000000000000..87f51facc59b
--- /dev/null
+++ b/lib/AST/ComparisonCategories.cpp
@@ -0,0 +1,211 @@
+//===- ComparisonCategories.cpp - Three Way Comparison Data -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the Comparison Category enum and data types, which
+// store the types and expressions needed to support operator<=>
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ComparisonCategories.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Type.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace clang;
+
+bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const {
+ assert(VD && "must have var decl");
+ if (!VD->checkInitIsICE())
+ return false;
+
+ // Before we attempt to get the value of the first field, ensure that we
+ // actually have one (and only one) field.
+ auto *Record = VD->getType()->getAsCXXRecordDecl();
+ if (std::distance(Record->field_begin(), Record->field_end()) != 1 ||
+ !Record->field_begin()->getType()->isIntegralOrEnumerationType())
+ return false;
+
+ return true;
+}
+
+/// Attempt to determine the integer value used to represent the comparison
+/// category result by evaluating the initializer for the specified VarDecl as
+/// a constant expression and retreiving the value of the class's first
+/// (and only) field.
+///
+/// Note: The STL types are expected to have the form:
+/// struct X { T value; };
+/// where T is an integral or enumeration type.
+llvm::APSInt ComparisonCategoryInfo::ValueInfo::getIntValue() const {
+ assert(hasValidIntValue() && "must have a valid value");
+ return VD->evaluateValue()->getStructField(0).getInt();
+}
+
+ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo(
+ ComparisonCategoryResult ValueKind) const {
+ // Check if we already have a cache entry for this value.
+ auto It = llvm::find_if(
+ Objects, [&](ValueInfo const &Info) { return Info.Kind == ValueKind; });
+ if (It != Objects.end())
+ return &(*It);
+
+ // We don't have a cached result. Lookup the variable declaration and create
+ // a new entry representing it.
+ DeclContextLookupResult Lookup = Record->getCanonicalDecl()->lookup(
+ &Ctx.Idents.get(ComparisonCategories::getResultString(ValueKind)));
+ if (Lookup.size() != 1 || !isa<VarDecl>(Lookup.front()))
+ return nullptr;
+ Objects.emplace_back(ValueKind, cast<VarDecl>(Lookup.front()));
+ return &Objects.back();
+}
+
+static const NamespaceDecl *lookupStdNamespace(const ASTContext &Ctx,
+ NamespaceDecl *&StdNS) {
+ if (!StdNS) {
+ DeclContextLookupResult Lookup =
+ Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get("std"));
+ if (Lookup.size() == 1)
+ StdNS = dyn_cast<NamespaceDecl>(Lookup.front());
+ }
+ return StdNS;
+}
+
+static CXXRecordDecl *lookupCXXRecordDecl(const ASTContext &Ctx,
+ const NamespaceDecl *StdNS,
+ ComparisonCategoryType Kind) {
+ StringRef Name = ComparisonCategories::getCategoryString(Kind);
+ DeclContextLookupResult Lookup = StdNS->lookup(&Ctx.Idents.get(Name));
+ if (Lookup.size() == 1)
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Lookup.front()))
+ return RD;
+ return nullptr;
+}
+
+const ComparisonCategoryInfo *
+ComparisonCategories::lookupInfo(ComparisonCategoryType Kind) const {
+ auto It = Data.find(static_cast<char>(Kind));
+ if (It != Data.end())
+ return &It->second;
+
+ if (const NamespaceDecl *NS = lookupStdNamespace(Ctx, StdNS))
+ if (CXXRecordDecl *RD = lookupCXXRecordDecl(Ctx, NS, Kind))
+ return &Data.try_emplace((char)Kind, Ctx, RD, Kind).first->second;
+
+ return nullptr;
+}
+
+const ComparisonCategoryInfo *
+ComparisonCategories::lookupInfoForType(QualType Ty) const {
+ assert(!Ty.isNull() && "type must be non-null");
+ using CCT = ComparisonCategoryType;
+ auto *RD = Ty->getAsCXXRecordDecl();
+ if (!RD)
+ return nullptr;
+
+ // Check to see if we have information for the specified type cached.
+ const auto *CanonRD = RD->getCanonicalDecl();
+ for (auto &KV : Data) {
+ const ComparisonCategoryInfo &Info = KV.second;
+ if (CanonRD == Info.Record->getCanonicalDecl())
+ return &Info;
+ }
+