aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /lib
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
downloadsrc-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.tar.gz
src-676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63.zip
Vendor import of clang trunk r351319 (just before the release_80 branchvendor/clang/clang-trunk-r351319
Notes
Notes: svn path=/vendor/clang/dist/; revision=343173 svn path=/vendor/clang/clang-trunk-r351319/; revision=343174; tag=vendor/clang/clang-trunk-r351319
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp6
-rw-r--r--lib/ARCMigrate/CMakeLists.txt1
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp2
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp124
-rw-r--r--lib/ARCMigrate/TransAPIUses.cpp2
-rw-r--r--lib/ARCMigrate/TransAutoreleasePool.cpp28
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp17
-rw-r--r--lib/ARCMigrate/TransGCCalls.cpp2
-rw-r--r--lib/ARCMigrate/TransProtectedScope.cpp7
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp22
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp19
-rw-r--r--lib/ARCMigrate/TransformActions.cpp2
-rw-r--r--lib/ARCMigrate/Transforms.cpp6
-rw-r--r--lib/AST/APValue.cpp20
-rw-r--r--lib/AST/ASTContext.cpp629
-rw-r--r--lib/AST/ASTDiagnostic.cpp14
-rw-r--r--lib/AST/ASTDumper.cpp1721
-rw-r--r--lib/AST/ASTImporter.cpp8084
-rw-r--r--lib/AST/ASTImporterLookupTable.cpp129
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp285
-rw-r--r--lib/AST/CMakeLists.txt6
-rw-r--r--lib/AST/CXXInheritance.cpp2
-rw-r--r--lib/AST/CommentLexer.cpp2
-rw-r--r--lib/AST/CommentParser.cpp1
-rw-r--r--lib/AST/CommentSema.cpp7
-rw-r--r--lib/AST/Decl.cpp230
-rw-r--r--lib/AST/DeclBase.cpp135
-rw-r--r--lib/AST/DeclCXX.cpp122
-rw-r--r--lib/AST/DeclObjC.cpp70
-rw-r--r--lib/AST/DeclOpenMP.cpp42
-rw-r--r--lib/AST/DeclPrinter.cpp19
-rw-r--r--lib/AST/DeclTemplate.cpp46
-rw-r--r--lib/AST/DeclarationName.cpp399
-rw-r--r--lib/AST/Expr.cpp669
-rw-r--r--lib/AST/ExprCXX.cpp1017
-rw-r--r--lib/AST/ExprClassification.cpp3
-rw-r--r--lib/AST/ExprConstant.cpp570
-rw-r--r--lib/AST/ExternalASTMerger.cpp10
-rw-r--r--lib/AST/FormatString.cpp (renamed from lib/Analysis/FormatString.cpp)52
-rw-r--r--lib/AST/FormatStringParsing.h (renamed from lib/Analysis/FormatStringParsing.h)6
-rw-r--r--lib/AST/ItaniumMangle.cpp65
-rw-r--r--lib/AST/Linkage.h11
-rw-r--r--lib/AST/Mangle.cpp6
-rw-r--r--lib/AST/MicrosoftMangle.cpp302
-rw-r--r--lib/AST/NSAPI.cpp17
-rw-r--r--lib/AST/NestedNameSpecifier.cpp37
-rw-r--r--lib/AST/ODRHash.cpp264
-rw-r--r--lib/AST/OSLog.cpp (renamed from lib/Analysis/OSLog.cpp)21
-rw-r--r--lib/AST/OpenMPClause.cpp579
-rw-r--r--lib/AST/ParentMap.cpp2
-rw-r--r--lib/AST/PrintfFormatString.cpp (renamed from lib/Analysis/PrintfFormatString.cpp)70
-rw-r--r--lib/AST/RawCommentList.cpp14
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp13
-rw-r--r--lib/AST/ScanfFormatString.cpp (renamed from lib/Analysis/ScanfFormatString.cpp)4
-rw-r--r--lib/AST/SelectorLocationsKind.cpp4
-rw-r--r--lib/AST/Stmt.cpp357
-rw-r--r--lib/AST/StmtCXX.cpp3
-rw-r--r--lib/AST/StmtObjC.cpp8
-rw-r--r--lib/AST/StmtOpenMP.cpp12
-rw-r--r--lib/AST/StmtPrinter.cpp619
-rw-r--r--lib/AST/StmtProfile.cpp23
-rw-r--r--lib/AST/TextNodeDumper.cpp1168
-rw-r--r--lib/AST/Type.cpp344
-rw-r--r--lib/AST/TypeLoc.cpp13
-rw-r--r--lib/AST/TypePrinter.cpp247
-rw-r--r--lib/AST/VTableBuilder.cpp33
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp27
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp22
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp106
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp47
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp19
-rw-r--r--lib/Analysis/BodyFarm.cpp60
-rw-r--r--lib/Analysis/CFG.cpp83
-rw-r--r--lib/Analysis/CMakeLists.txt7
-rw-r--r--lib/Analysis/CallGraph.cpp2
-rw-r--r--lib/Analysis/CloneDetection.cpp19
-rw-r--r--lib/Analysis/Consumed.cpp26
-rw-r--r--lib/Analysis/ExprMutationAnalyzer.cpp445
-rw-r--r--lib/Analysis/LiveVariables.cpp61
-rw-r--r--lib/Analysis/ProgramPoint.cpp175
-rw-r--r--lib/Analysis/PseudoConstantAnalysis.cpp226
-rw-r--r--lib/Analysis/ReachableCode.cpp22
-rw-r--r--lib/Analysis/ThreadSafety.cpp410
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp59
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp18
-rw-r--r--lib/Basic/Attributes.cpp9
-rw-r--r--lib/Basic/Builtins.cpp2
-rw-r--r--lib/Basic/CMakeLists.txt5
-rw-r--r--lib/Basic/CodeGenOptions.cpp (renamed from lib/Frontend/CodeGenOptions.cpp)4
-rw-r--r--lib/Basic/Cuda.cpp27
-rw-r--r--lib/Basic/Diagnostic.cpp15
-rw-r--r--lib/Basic/FileManager.cpp97
-rw-r--r--lib/Basic/FileSystemStatCache.cpp33
-rw-r--r--lib/Basic/FixedPoint.cpp115
-rw-r--r--lib/Basic/IdentifierTable.cpp110
-rw-r--r--lib/Basic/Module.cpp47
-rw-r--r--lib/Basic/OpenMPKinds.cpp46
-rw-r--r--lib/Basic/SourceLocation.cpp55
-rw-r--r--lib/Basic/SourceManager.cpp80
-rw-r--r--lib/Basic/TargetInfo.cpp7
-rw-r--r--lib/Basic/Targets.cpp26
-rw-r--r--lib/Basic/Targets/AArch64.cpp17
-rw-r--r--lib/Basic/Targets/AArch64.h1
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp84
-rw-r--r--lib/Basic/Targets/AMDGPU.h214
-rw-r--r--lib/Basic/Targets/ARC.cpp25
-rw-r--r--lib/Basic/Targets/ARC.h74
-rw-r--r--lib/Basic/Targets/ARM.cpp17
-rw-r--r--lib/Basic/Targets/Hexagon.cpp18
-rw-r--r--lib/Basic/Targets/Mips.cpp65
-rw-r--r--lib/Basic/Targets/Mips.h29
-rw-r--r--lib/Basic/Targets/NVPTX.cpp5
-rw-r--r--lib/Basic/Targets/Nios2.cpp56
-rw-r--r--lib/Basic/Targets/Nios2.h151
-rw-r--r--lib/Basic/Targets/OSTargets.cpp2
-rw-r--r--lib/Basic/Targets/OSTargets.h49
-rw-r--r--lib/Basic/Targets/PPC.cpp34
-rw-r--r--lib/Basic/Targets/PPC.h5
-rw-r--r--lib/Basic/Targets/Sparc.h2
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp49
-rw-r--r--lib/Basic/Targets/WebAssembly.h15
-rw-r--r--lib/Basic/Targets/X86.cpp30
-rw-r--r--lib/Basic/Targets/X86.h13
-rw-r--r--lib/Basic/VirtualFileSystem.cpp2026
-rw-r--r--lib/CodeGen/BackendUtil.cpp129
-rw-r--r--lib/CodeGen/CGAtomic.cpp28
-rw-r--r--lib/CodeGen/CGBlocks.cpp886
-rw-r--r--lib/CodeGen/CGBlocks.h10
-rw-r--r--lib/CodeGen/CGBuiltin.cpp1787
-rw-r--r--lib/CodeGen/CGCUDANV.cpp33
-rw-r--r--lib/CodeGen/CGCXX.cpp4
-rw-r--r--lib/CodeGen/CGCXXABI.cpp2
-rw-r--r--lib/CodeGen/CGCall.cpp128
-rw-r--r--lib/CodeGen/CGCall.h14
-rw-r--r--lib/CodeGen/CGClass.cpp33
-rw-r--r--lib/CodeGen/CGCleanup.cpp4
-rw-r--r--lib/CodeGen/CGCoroutine.cpp14
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp505
-rw-r--r--lib/CodeGen/CGDebugInfo.h64
-rw-r--r--lib/CodeGen/CGDecl.cpp568
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp103
-rw-r--r--lib/CodeGen/CGException.cpp45
-rw-r--r--lib/CodeGen/CGExpr.cpp159
-rw-r--r--lib/CodeGen/CGExprAgg.cpp9
-rw-r--r--lib/CodeGen/CGExprCXX.cpp36
-rw-r--r--lib/CodeGen/CGExprComplex.cpp8
-rw-r--r--lib/CodeGen/CGExprConstant.cpp46
-rw-r--r--lib/CodeGen/CGExprScalar.cpp455
-rw-r--r--lib/CodeGen/CGLoopInfo.cpp129
-rw-r--r--lib/CodeGen/CGLoopInfo.h33
-rw-r--r--lib/CodeGen/CGNonTrivialStruct.cpp31
-rw-r--r--lib/CodeGen/CGObjC.cpp511
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp335
-rw-r--r--lib/CodeGen/CGObjCMac.cpp84
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp60
-rw-r--r--lib/CodeGen/CGObjCRuntime.h7
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp40
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.h5
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp1079
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h117
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp2371
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.h99
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp2
-rw-r--r--lib/CodeGen/CGStmt.cpp54
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp443
-rw-r--r--lib/CodeGen/CGVTT.cpp6
-rw-r--r--lib/CodeGen/CGVTables.cpp27
-rw-r--r--lib/CodeGen/CGValue.h5
-rw-r--r--lib/CodeGen/CMakeLists.txt1
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp1
-rw-r--r--lib/CodeGen/CodeGenAction.cpp17
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp325
-rw-r--r--lib/CodeGen/CodeGenFunction.h179
-rw-r--r--lib/CodeGen/CodeGenModule.cpp648
-rw-r--r--lib/CodeGen/CodeGenModule.h50
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp11
-rw-r--r--lib/CodeGen/CodeGenPGO.h1
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp3
-rw-r--r--lib/CodeGen/CodeGenTypes.h1
-rw-r--r--lib/CodeGen/ConstantEmitter.h3
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp107
-rw-r--r--lib/CodeGen/CoverageMappingGen.h1
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp103
-rw-r--r--lib/CodeGen/MacroPPCallbacks.cpp17
-rw-r--r--lib/CodeGen/MacroPPCallbacks.h5
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp22
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp34
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp5
-rw-r--r--lib/CodeGen/SwiftCallingConv.cpp40
-rw-r--r--lib/CodeGen/TargetInfo.cpp331
-rw-r--r--lib/CodeGen/VarBypassDetector.cpp2
-rw-r--r--lib/CodeGen/VarBypassDetector.h1
-rw-r--r--lib/CrossTU/CrossTranslationUnit.cpp138
-rw-r--r--lib/Driver/Action.cpp16
-rw-r--r--lib/Driver/CMakeLists.txt5
-rw-r--r--lib/Driver/Compilation.cpp2
-rw-r--r--lib/Driver/DarwinSDKInfo.cpp44
-rw-r--r--lib/Driver/Distro.cpp9
-rw-r--r--lib/Driver/Driver.cpp478
-rw-r--r--lib/Driver/Job.cpp19
-rw-r--r--lib/Driver/SanitizerArgs.cpp51
-rw-r--r--lib/Driver/ToolChain.cpp49
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp13
-rw-r--r--lib/Driver/ToolChains/AMDGPU.h4
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp185
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.h5
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp58
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h2
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp12
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp10
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h2
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp34
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp9
-rw-r--r--lib/Driver/ToolChains/Clang.cpp889
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp200
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h6
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp1
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp122
-rw-r--r--lib/Driver/ToolChains/Cuda.h2
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp322
-rw-r--r--lib/Driver/ToolChains/Darwin.h21
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp2
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp22
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp199
-rw-r--r--lib/Driver/ToolChains/HIP.cpp59
-rw-r--r--lib/Driver/ToolChains/HIP.h5
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp17
-rw-r--r--lib/Driver/ToolChains/Hexagon.h3
-rw-r--r--lib/Driver/ToolChains/Hurd.cpp169
-rw-r--r--lib/Driver/ToolChains/Hurd.h46
-rw-r--r--lib/Driver/ToolChains/Linux.cpp147
-rw-r--r--lib/Driver/ToolChains/Linux.h2
-rw-r--r--lib/Driver/ToolChains/MSP430.cpp233
-rw-r--r--lib/Driver/ToolChains/MSP430.h71
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp35
-rw-r--r--lib/Driver/ToolChains/MSVC.h13
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp66
-rw-r--r--lib/Driver/ToolChains/MinGW.h6
-rw-r--r--lib/Driver/ToolChains/Minix.cpp4
-rw-r--r--lib/Driver/ToolChains/MipsLinux.h2
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp14
-rw-r--r--lib/Driver/ToolChains/NetBSD.h4
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp66
-rw-r--r--lib/Driver/ToolChains/OpenBSD.h8
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp6
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.cpp (renamed from lib/Driver/ToolChains/RISCV.cpp)38
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.h (renamed from lib/Driver/ToolChains/RISCV.h)14
-rw-r--r--lib/Driver/ToolChains/Solaris.h2
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp55
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h17
-rw-r--r--lib/Driver/Types.cpp2
-rw-r--r--lib/Driver/XRayArgs.cpp33
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp20
-rw-r--r--lib/Format/BreakableToken.cpp38
-rw-r--r--lib/Format/ContinuationIndenter.cpp54
-rw-r--r--lib/Format/Format.cpp216
-rw-r--r--lib/Format/FormatToken.h29
-rw-r--r--lib/Format/FormatTokenLexer.cpp11
-rw-r--r--lib/Format/FormatTokenLexer.h4
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp7
-rw-r--r--lib/Format/TokenAnnotator.cpp70
-rw-r--r--lib/Format/TokenAnnotator.h7
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp23
-rw-r--r--lib/Format/UnwrappedLineParser.cpp53
-rw-r--r--lib/Format/UnwrappedLineParser.h1
-rw-r--r--lib/Format/WhitespaceManager.cpp10
-rw-r--r--lib/Frontend/ASTConsumers.cpp362
-rw-r--r--lib/Frontend/ASTMerge.cpp11
-rw-r--r--lib/Frontend/ASTUnit.cpp52
-rw-r--r--lib/Frontend/CMakeLists.txt3
-rw-r--r--lib/Frontend/CacheTokens.cpp700
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp1
-rw-r--r--lib/Frontend/CompilerInstance.cpp69
-rw-r--r--lib/Frontend/CompilerInvocation.cpp409
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp2
-rw-r--r--lib/Frontend/DependencyFile.cpp38
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp4
-rw-r--r--lib/Frontend/FrontendAction.cpp67
-rw-r--r--lib/Frontend/FrontendActions.cpp103
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp27
-rw-r--r--lib/Frontend/InitPreprocessor.cpp41
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp4
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp52
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp5
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp1
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp339
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp262
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp25
-rw-r--r--lib/Headers/CMakeLists.txt6
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h8
-rw-r--r--lib/Headers/adxintrin.h4
-rw-r--r--lib/Headers/altivec.h123
-rw-r--r--lib/Headers/avx512bwintrin.h839
-rw-r--r--lib/Headers/avx512dqintrin.h302
-rw-r--r--lib/Headers/avx512fintrin.h177
-rw-r--r--lib/Headers/avx512pfintrin.h32
-rw-r--r--lib/Headers/avx512vbmi2intrin.h158
-rw-r--r--lib/Headers/avx512vbmiintrin.h26
-rw-r--r--lib/Headers/avx512vbmivlintrin.h56
-rw-r--r--lib/Headers/avx512vlbwintrin.h75
-rw-r--r--lib/Headers/avx512vlintrin.h349
-rw-r--r--lib/Headers/avx512vlvbmi2intrin.h312
-rw-r--r--lib/Headers/bmiintrin.h10
-rw-r--r--lib/Headers/cuda_wrappers/new6
-rw-r--r--lib/Headers/emmintrin.h107
-rw-r--r--lib/Headers/float.h12
-rw-r--r--lib/Headers/immintrin.h59
-rw-r--r--lib/Headers/intrin.h546
-rw-r--r--lib/Headers/lzcntintrin.h22
-rw-r--r--lib/Headers/opencl-c.h659
-rw-r--r--lib/Headers/unwind.h4
-rw-r--r--lib/Headers/vecintrin.h6
-rw-r--r--lib/Index/CommentToXML.cpp1
-rw-r--r--lib/Index/IndexBody.cpp41
-rw-r--r--lib/Index/IndexDecl.cpp2
-rw-r--r--lib/Index/IndexSymbol.cpp5
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp14
-rw-r--r--lib/Index/IndexingAction.cpp24
-rw-r--r--lib/Index/IndexingContext.cpp26
-rw-r--r--lib/Index/SimpleFormatContext.h10
-rw-r--r--lib/Index/USRGeneration.cpp54
-rw-r--r--lib/Lex/CMakeLists.txt1
-rw-r--r--lib/Lex/HeaderMap.cpp5
-rw-r--r--lib/Lex/HeaderSearch.cpp49
-rw-r--r--lib/Lex/Lexer.cpp78
-rw-r--r--lib/Lex/LiteralSupport.cpp2
-rw-r--r--lib/Lex/MacroInfo.cpp3
-rw-r--r--lib/Lex/ModuleMap.cpp66
-rw-r--r--lib/Lex/PPDirectives.cpp201
-rw-r--r--lib/Lex/PPLexerChange.cpp109
-rw-r--r--lib/Lex/PPMacroExpansion.cpp13
-rw-r--r--lib/Lex/PTHLexer.cpp748
-rw-r--r--lib/Lex/Pragma.cpp57
-rw-r--r--lib/Lex/Preprocessor.cpp68
-rw-r--r--lib/Lex/TokenConcatenation.cpp4
-rw-r--r--lib/Parse/ParseAST.cpp34
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp10
-rw-r--r--lib/Parse/ParseDecl.cpp124
-rw-r--r--lib/Parse/ParseDeclCXX.cpp200
-rw-r--r--lib/Parse/ParseExpr.cpp86
-rw-r--r--lib/Parse/ParseExprCXX.cpp111
-rw-r--r--lib/Parse/ParseInit.cpp6
-rw-r--r--lib/Parse/ParseObjc.cpp41
-rw-r--r--lib/Parse/ParseOpenMP.cpp390
-rw-r--r--lib/Parse/ParsePragma.cpp273
-rw-r--r--lib/Parse/ParseStmt.cpp151
-rw-r--r--lib/Parse/ParseTemplate.cpp77
-rw-r--r--lib/Parse/ParseTentative.cpp105
-rw-r--r--lib/Parse/Parser.cpp23
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp2
-rw-r--r--lib/Rewrite/RewriteRope.cpp4
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp135
-rw-r--r--lib/Sema/CMakeLists.txt1
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp222
-rw-r--r--lib/Sema/DeclSpec.cpp63
-rw-r--r--lib/Sema/IdentifierResolver.cpp14
-rw-r--r--lib/Sema/JumpDiagnostics.cpp16
-rw-r--r--lib/Sema/ParsedAttr.cpp49
-rw-r--r--lib/Sema/ScopeInfo.cpp2
-rw-r--r--lib/Sema/Sema.cpp135
-rw-r--r--lib/Sema/SemaAccess.cpp47
-rw-r--r--lib/Sema/SemaAttr.cpp112
-rw-r--r--lib/Sema/SemaCUDA.cpp2
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp24
-rw-r--r--lib/Sema/SemaCast.cpp105
-rw-r--r--lib/Sema/SemaChecking.cpp2758
-rw-r--r--lib/Sema/SemaCodeComplete.cpp3022
-rw-r--r--lib/Sema/SemaCoroutine.cpp43
-rw-r--r--lib/Sema/SemaDecl.cpp959
-rw-r--r--lib/Sema/SemaDeclAttr.cpp1214
-rw-r--r--lib/Sema/SemaDeclCXX.cpp814
-rw-r--r--lib/Sema/SemaDeclObjC.cpp52
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp54
-rw-r--r--lib/Sema/SemaExpr.cpp1157
-rw-r--r--lib/Sema/SemaExprCXX.cpp389
-rw-r--r--lib/Sema/SemaExprMember.cpp30
-rw-r--r--lib/Sema/SemaExprObjC.cpp240
-rw-r--r--lib/Sema/SemaInit.cpp710
-rw-r--r--lib/Sema/SemaLambda.cpp157
-rw-r--r--lib/Sema/SemaLookup.cpp161
-rw-r--r--lib/Sema/SemaObjCProperty.cpp42
-rw-r--r--lib/Sema/SemaOpenMP.cpp1749
-rw-r--r--lib/Sema/SemaOverload.cpp628
-rw-r--r--lib/Sema/SemaPseudoObject.cpp2
-rw-r--r--lib/Sema/SemaStmt.cpp429
-rw-r--r--lib/Sema/SemaStmtAsm.cpp160
-rw-r--r--lib/Sema/SemaStmtAttr.cpp99
-rw-r--r--lib/Sema/SemaTemplate.cpp396
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp19
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp53
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp352
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp9
-rw-r--r--lib/Sema/SemaType.cpp1013
-rw-r--r--lib/Sema/TreeTransform.h703
-rw-r--r--lib/Serialization/ASTCommon.cpp6
-rw-r--r--lib/Serialization/ASTReader.cpp1024
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp300
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp1294
-rw-r--r--lib/Serialization/ASTWriter.cpp555
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp110
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp675
-rw-r--r--lib/Serialization/CMakeLists.txt1
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp2
-rw-r--r--lib/Serialization/ModuleManager.cpp19
-rw-r--r--lib/Serialization/PCHContainerOperations.cpp (renamed from lib/Frontend/PCHContainerOperations.cpp)4
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationDiagnostics.cpp24
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationDiagnostics.h31
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationState.h5
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp27
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp102
-rw-r--r--lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt14
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp150
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp46
-rw-r--r--lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp103
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp31
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ClangCheckers.cpp32
-rw-r--r--lib/StaticAnalyzer/Checkers/ClangSACheckers.h37
-rw-r--r--lib/StaticAnalyzer/Checkers/CloneChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/ConversionChecker.cpp57
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp128
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp115
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/GTestChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp216
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp158
-rw-r--r--lib/StaticAnalyzer/Checkers/InterCheckerAPI.h3
-rw-r--r--lib/StaticAnalyzer/Checkers/IteratorChecker.cpp1414
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h1
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp53
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp161
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp525
-rw-r--r--lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/MoveChecker.cpp740
-rw-r--r--lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp42
-rw-r--r--lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp19
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/PaddingChecker.cpp45
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp4156
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp1547
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h393
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp794
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h85
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp36
-rw-r--r--lib/StaticAnalyzer/Checkers/SelectorExtras.h46
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp36
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp195
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h349
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp538
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp282
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp688
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/ValistChecker.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/VforkChecker.cpp2
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp49
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp483
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp141
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp750
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt9
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp162
-rw-r--r--lib/StaticAnalyzer/Core/Checker.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/CheckerHelpers.cpp8
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/CheckerRegistry.cpp190
-rw-r--r--lib/StaticAnalyzer/Core/CommonBugCategories.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp32
-rw-r--r--lib/StaticAnalyzer/Core/DynamicTypeMap.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp22
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp30
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp545
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp125
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp93
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp63
-rw-r--r--lib/StaticAnalyzer/Core/LoopWidening.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp81
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp44
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp892
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp99
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp175
-rw-r--r--lib/StaticAnalyzer/Core/RetainSummaryManager.cpp1229
-rw-r--r--lib/StaticAnalyzer/Core/SMTConstraintManager.cpp181
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp15
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/SarifDiagnostics.cpp349
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp26
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp45
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/TaintManager.cpp23
-rw-r--r--lib/StaticAnalyzer/Core/WorkList.cpp62
-rw-r--r--lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp304
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp156
-rw-r--r--lib/StaticAnalyzer/Frontend/CMakeLists.txt1
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp196
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp247
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.cpp2
-rw-r--r--lib/StaticAnalyzer/README.txt12
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp7
-rw-r--r--lib/Tooling/AllTUsExecution.cpp32
-rw-r--r--lib/Tooling/CMakeLists.txt1
-rw-r--r--lib/Tooling/CompilationDatabase.cpp39
-rw-r--r--lib/Tooling/Core/Diagnostic.cpp9
-rw-r--r--lib/Tooling/Core/Lookup.cpp44
-rw-r--r--lib/Tooling/Core/Replacement.cpp17
-rw-r--r--lib/Tooling/Execution.cpp2
-rw-r--r--lib/Tooling/Inclusions/HeaderIncludes.cpp12
-rw-r--r--lib/Tooling/InterpolatingCompilationDatabase.cpp277
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp5
-rw-r--r--lib/Tooling/Refactoring/ASTSelection.cpp2
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp6
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFinder.cpp4
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp8
-rw-r--r--lib/Tooling/StandaloneExecution.cpp2
-rw-r--r--lib/Tooling/Tooling.cpp123
583 files changed, 55835 insertions, 38806 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 3c7b593be6d4..6da87903a488 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -190,8 +190,6 @@ createInvocationForMigration(CompilerInvocation &origCI,
PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile);
PPOpts.ImplicitPCHInclude.clear();
}
- // FIXME: Get the original header of a PTH as well.
- CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
std::string define = getARCMTMacroName();
define += '=';
CInvok->getPreprocessorOpts().addMacroDef(define);
@@ -241,7 +239,7 @@ bool arcmt::checkForManualIssues(
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors,
StringRef plistOut) {
- if (!origCI.getLangOpts()->ObjC1)
+ if (!origCI.getLangOpts()->ObjC)
return false;
LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC();
@@ -342,7 +340,7 @@ applyTransforms(CompilerInvocation &origCI, const FrontendInputFile &Input,
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
DiagnosticConsumer *DiagClient, StringRef outputDir,
bool emitPremigrationARCErrors, StringRef plistOut) {
- if (!origCI.getLangOpts()->ObjC1)
+ if (!origCI.getLangOpts()->ObjC)
return false;
LangOptions::GCMode OrigGCMode = origCI.getLangOpts()->getGC();
diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index b716a20fe63f..efdff279aaed 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -35,4 +35,5 @@ add_clang_library(clangARCMigrate
clangSema
clangSerialization
clangStaticAnalyzerCheckers
+ clangStaticAnalyzerCore
)
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index ccc8c9ee30ff..225f47119b00 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -226,7 +226,7 @@ void FileRemapper::remap(const FileEntry *file, const FileEntry *newfile) {
const FileEntry *FileRemapper::getOriginalFile(StringRef filePath) {
const FileEntry *file = FileMgr->getFile(filePath);
- // If we are updating a file that overriden an original file,
+ // If we are updating a file that overridden an original file,
// actually update the original file.
llvm::DenseMap<const FileEntry *, const FileEntry *>::iterator
I = ToFromMappings.find(file);
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index 7e9bc6a5bdc6..6950ce0e12f3 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -27,7 +27,7 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
+#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
@@ -36,7 +36,7 @@
using namespace clang;
using namespace arcmt;
-using namespace ento::objc_retain;
+using namespace ento;
namespace {
@@ -261,7 +261,7 @@ namespace {
if (IsGetter) {
// Find space location range between receiver expression and getter method.
SourceLocation BegLoc =
- ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getLocEnd();
+ ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc();
BegLoc = PP.getLocForEndOfToken(BegLoc);
SourceLocation EndLoc = Msg->getSelectorLoc(0);
SourceRange SpaceRange(BegLoc, EndLoc);
@@ -269,7 +269,7 @@ namespace {
// rewrite getter method expression into: receiver.property or
// (receiver).property
if (NeedsParen) {
- commit.insertBefore(receiver->getLocStart(), "(");
+ commit.insertBefore(receiver->getBeginLoc(), "(");
PropertyDotString = ").";
}
else
@@ -291,9 +291,9 @@ namespace {
if (!RHS)
return false;
SourceLocation BegLoc =
- ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getLocEnd();
+ ReceiverIsSuper ? Msg->getSuperLoc() : receiver->getEndLoc();
BegLoc = PP.getLocForEndOfToken(BegLoc);
- SourceLocation EndLoc = RHS->getLocStart();
+ SourceLocation EndLoc = RHS->getBeginLoc();
EndLoc = EndLoc.getLocWithOffset(-1);
const char *colon = PP.getSourceManager().getCharacterData(EndLoc);
// Add a space after '=' if there is no space between RHS and '='
@@ -545,14 +545,14 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
SourceLocation EndGetterSelectorLoc =
StartGetterSelectorLoc.getLocWithOffset(GetterSelector.getNameForSlot(0).size());
- commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
+ commit.replace(CharSourceRange::getCharRange(Getter->getBeginLoc(),
EndGetterSelectorLoc),
PropertyString);
if (Setter && AvailabilityArgsMatch) {
SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
// Get location past ';'
EndLoc = EndLoc.getLocWithOffset(1);
- SourceLocation BeginOfSetterDclLoc = Setter->getLocStart();
+ SourceLocation BeginOfSetterDclLoc = Setter->getBeginLoc();
// FIXME. This assumes that setter decl; is immediately preceded by eoln.
// It is trying to remove the setter method decl. line entirely.
BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1);
@@ -720,32 +720,33 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
ClassString += TypedefDcl->getIdentifier()->getName();
ClassString += ')';
- SourceRange R(EnumDcl->getLocStart(), EnumDcl->getLocStart());
+ SourceRange R(EnumDcl->getBeginLoc(), EnumDcl->getBeginLoc());
commit.replace(R, ClassString);
- SourceLocation EndOfEnumDclLoc = EnumDcl->getLocEnd();
+ SourceLocation EndOfEnumDclLoc = EnumDcl->getEndLoc();
EndOfEnumDclLoc = trans::findSemiAfterLocation(EndOfEnumDclLoc,
NS.getASTContext(), /*IsDecl*/true);
if (EndOfEnumDclLoc.isValid()) {
- SourceRange EnumDclRange(EnumDcl->getLocStart(), EndOfEnumDclLoc);
- commit.insertFromRange(TypedefDcl->getLocStart(), EnumDclRange);
+ SourceRange EnumDclRange(EnumDcl->getBeginLoc(), EndOfEnumDclLoc);
+ commit.insertFromRange(TypedefDcl->getBeginLoc(), EnumDclRange);
}
else
return false;
- SourceLocation EndTypedefDclLoc = TypedefDcl->getLocEnd();
+ SourceLocation EndTypedefDclLoc = TypedefDcl->getEndLoc();
EndTypedefDclLoc = trans::findSemiAfterLocation(EndTypedefDclLoc,
NS.getASTContext(), /*IsDecl*/true);
if (EndTypedefDclLoc.isValid()) {
- SourceRange TDRange(TypedefDcl->getLocStart(), EndTypedefDclLoc);
+ SourceRange TDRange(TypedefDcl->getBeginLoc(), EndTypedefDclLoc);
commit.remove(TDRange);
}
else
return false;
- EndOfEnumDclLoc = trans::findLocationAfterSemi(EnumDcl->getLocEnd(), NS.getASTContext(),
- /*IsDecl*/true);
+ EndOfEnumDclLoc =
+ trans::findLocationAfterSemi(EnumDcl->getEndLoc(), NS.getASTContext(),
+ /*IsDecl*/ true);
if (EndOfEnumDclLoc.isValid()) {
- SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
+ SourceLocation BeginOfEnumDclLoc = EnumDcl->getBeginLoc();
// FIXME. This assumes that enum decl; is immediately preceded by eoln.
// It is trying to remove the enum decl. lines entirely.
BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
@@ -775,12 +776,13 @@ static void rewriteToNSMacroDecl(ASTContext &Ctx,
SourceLocation EndLoc = EnumDcl->getBraceRange().getBegin();
if (EndLoc.isInvalid())
return;
- CharSourceRange R = CharSourceRange::getCharRange(EnumDcl->getLocStart(), EndLoc);
+ CharSourceRange R =
+ CharSourceRange::getCharRange(EnumDcl->getBeginLoc(), EndLoc);
commit.replace(R, ClassString);
// This is to remove spaces between '}' and typedef name.
- SourceLocation StartTypedefLoc = EnumDcl->getLocEnd();
+ SourceLocation StartTypedefLoc = EnumDcl->getEndLoc();
StartTypedefLoc = StartTypedefLoc.getLocWithOffset(+1);
- SourceLocation EndTypedefLoc = TypedefDcl->getLocEnd();
+ SourceLocation EndTypedefLoc = TypedefDcl->getEndLoc();
commit.remove(SourceRange(StartTypedefLoc, EndTypedefLoc));
}
@@ -811,7 +813,7 @@ static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx,
}
if (AllHexdecimalEnumerator && EnumVal) {
bool FoundHexdecimalEnumerator = false;
- SourceLocation EndLoc = Enumerator->getLocEnd();
+ SourceLocation EndLoc = Enumerator->getEndLoc();
Token Tok;
if (!PP.getRawToken(EndLoc, Tok, /*IgnoreWhiteSpace=*/true))
if (Tok.isLiteral() && Tok.getLength() > 2) {
@@ -928,7 +930,7 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
if (const EnumType *EnumTy = qt->getAs<EnumType>()) {
if (EnumTy->getDecl() == EnumDcl) {
bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
- if (!InsertFoundation(Ctx, TypedefDcl->getLocStart()))
+ if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc()))
return false;
edit::Commit commit(*Editor);
rewriteToNSMacroDecl(Ctx, EnumDcl, TypedefDcl, *NSAPIObj, commit, !NSOptions);
@@ -941,7 +943,7 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
// We may still use NS_OPTIONS based on what we find in the enumertor list.
bool NSOptions = UseNSOptionsMacro(PP, Ctx, EnumDcl);
- if (!InsertFoundation(Ctx, TypedefDcl->getLocStart()))
+ if (!InsertFoundation(Ctx, TypedefDcl->getBeginLoc()))
return false;
edit::Commit commit(*Editor);
bool Res = rewriteToNSEnumDecl(EnumDcl, TypedefDcl, *NSAPIObj,
@@ -964,7 +966,7 @@ static void ReplaceWithInstancetype(ASTContext &Ctx,
ClassString = "instancetype";
}
else {
- R = SourceRange(OM->getLocStart(), OM->getLocStart());
+ R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc());
ClassString = OM->isInstanceMethod() ? '-' : '+';
ClassString += " (instancetype)";
}
@@ -986,7 +988,7 @@ static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC,
}
}
else {
- R = SourceRange(OM->getLocStart(), OM->getLocStart());
+ R = SourceRange(OM->getBeginLoc(), OM->getBeginLoc());
ClassString = "+ (";
ClassString += IDecl->getName(); ClassString += "*)";
}
@@ -1257,7 +1259,7 @@ void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
return;
edit::Commit commit(*Editor);
- commit.insertBefore(OM->getLocEnd(), " NS_RETURNS_INNER_POINTER");
+ commit.insertBefore(OM->getEndLoc(), " NS_RETURNS_INNER_POINTER");
Editor->commit(commit);
}
@@ -1269,7 +1271,7 @@ void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ct
!NSAPIObj->isMacroDefined("NS_RETURNS_INNER_POINTER"))
return;
edit::Commit commit(*Editor);
- commit.insertBefore(P->getLocEnd(), " NS_RETURNS_INNER_POINTER ");
+ commit.insertBefore(P->getEndLoc(), " NS_RETURNS_INNER_POINTER ");
Editor->commit(commit);
}
@@ -1395,9 +1397,9 @@ void ObjCMigrateASTConsumer::AnnotateImplicitBridging(ASTContext &Ctx) {
CFFunctionIBCandidates[CFFunctionIBCandidates.size()-1];
const char *PragmaString = "\nCF_IMPLICIT_BRIDGING_ENABLED\n\n";
edit::Commit commit(*Editor);
- commit.insertBefore(FirstFD->getLocStart(), PragmaString);
+ commit.insertBefore(FirstFD->getBeginLoc(), PragmaString);
PragmaString = "\n\nCF_IMPLICIT_BRIDGING_DISABLED\n";
- SourceLocation EndLoc = LastFD->getLocEnd();
+ SourceLocation EndLoc = LastFD->getEndLoc();
// get location just past end of function location.
EndLoc = PP.getLocForEndOfToken(EndLoc);
if (isa<FunctionDecl>(LastFD)) {
@@ -1458,21 +1460,21 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
const char *AnnotationString = nullptr;
- if (Ret.getObjKind() == RetEffect::CF) {
+ if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
AnnotationString = " CF_RETURNS_RETAINED";
else if (Ret.notOwned() &&
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
AnnotationString = " CF_RETURNS_NOT_RETAINED";
}
- else if (Ret.getObjKind() == RetEffect::ObjC) {
+ else if (Ret.getObjKind() == ObjKind::ObjC) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("NS_RETURNS_RETAINED"))
AnnotationString = " NS_RETURNS_RETAINED";
}
if (AnnotationString) {
edit::Commit commit(*Editor);
- commit.insertAfterToken(FuncDecl->getLocEnd(), AnnotationString);
+ commit.insertAfterToken(FuncDecl->getEndLoc(), AnnotationString);
Editor->commit(commit);
}
}
@@ -1482,14 +1484,15 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
ArgEffect AE = AEArgs[i];
- if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
+ if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
+ !pd->hasAttr<CFConsumedAttr>() &&
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
Editor->commit(commit);
- }
- else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
- NSAPIObj->isMacroDefined("NS_CONSUMED")) {
+ } else if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::ObjC &&
+ !pd->hasAttr<NSConsumedAttr>() &&
+ NSAPIObj->isMacroDefined("NS_CONSUMED")) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
Editor->commit(commit);
@@ -1518,7 +1521,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
bool ReturnCFAudited = false;
if (!FuncIsReturnAnnotated) {
RetEffect Ret = CE.getReturnValue();
- if (Ret.getObjKind() == RetEffect::CF &&
+ if (Ret.getObjKind() == ObjKind::CF &&
(Ret.isOwned() || Ret.notOwned()))
ReturnCFAudited = true;
else if (!AuditedType(FuncDecl->getReturnType()))
@@ -1534,13 +1537,13 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
ArgEffect AE = AEArgs[i];
- if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
- if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>())
+ if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
+ AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
+ if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>())
ArgCFAudited = true;
- else if (AE == IncRef)
+ else if (AE.getKind() == IncRef)
ArgCFAudited = true;
- }
- else {
+ } else {
QualType AT = pd->getType();
if (!AuditedType(AT)) {
AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
@@ -1572,14 +1575,14 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
const char *AnnotationString = nullptr;
- if (Ret.getObjKind() == RetEffect::CF) {
+ if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
AnnotationString = " CF_RETURNS_RETAINED";
else if (Ret.notOwned() &&
NSAPIObj->isMacroDefined("CF_RETURNS_NOT_RETAINED"))
AnnotationString = " CF_RETURNS_NOT_RETAINED";
}
- else if (Ret.getObjKind() == RetEffect::ObjC) {
+ else if (Ret.getObjKind() == ObjKind::ObjC) {
ObjCMethodFamily OMF = MethodDecl->getMethodFamily();
switch (OMF) {
case clang::OMF_alloc:
@@ -1598,7 +1601,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
if (AnnotationString) {
edit::Commit commit(*Editor);
- commit.insertBefore(MethodDecl->getLocEnd(), AnnotationString);
+ commit.insertBefore(MethodDecl->getEndLoc(), AnnotationString);
Editor->commit(commit);
}
}
@@ -1608,7 +1611,9 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
ArgEffect AE = AEArgs[i];
- if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
+ if (AE.getKind() == DecRef
+ && AE.getObjKind() == ObjKind::CF
+ && !pd->hasAttr<CFConsumedAttr>() &&
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1624,19 +1629,20 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
return;
CallEffects CE = CallEffects::getEffect(MethodDecl);
- bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
- MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
- MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
- MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
- MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
-
- if (CE.getReceiver() == DecRefMsg &&
+ bool MethodIsReturnAnnotated =
+ (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
+ MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
+
+ if (CE.getReceiver().getKind() == DecRef &&
!MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
MethodDecl->getMethodFamily() != OMF_init &&
MethodDecl->getMethodFamily() != OMF_release &&
NSAPIObj->isMacroDefined("NS_CONSUMES_SELF")) {
edit::Commit commit(*Editor);
- commit.insertBefore(MethodDecl->getLocEnd(), " NS_CONSUMES_SELF");
+ commit.insertBefore(MethodDecl->getEndLoc(), " NS_CONSUMES_SELF");
Editor->commit(commit);
}
@@ -1647,8 +1653,8 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
if (!MethodIsReturnAnnotated) {
RetEffect Ret = CE.getReturnValue();
- if ((Ret.getObjKind() == RetEffect::CF ||
- Ret.getObjKind() == RetEffect::ObjC) &&
+ if ((Ret.getObjKind() == ObjKind::CF ||
+ Ret.getObjKind() == ObjKind::ObjC) &&
(Ret.isOwned() || Ret.notOwned())) {
AddCFAnnotations(Ctx, CE, MethodDecl, false);
return;
@@ -1664,8 +1670,8 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
ArgEffect AE = AEArgs[i];
- if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef ||
- !AuditedType(pd->getType())) {
+ if ((AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>()) ||
+ AE.getKind() == IncRef || !AuditedType(pd->getType())) {
AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
return;
}
@@ -1713,7 +1719,7 @@ void ObjCMigrateASTConsumer::inferDesignatedInitializers(
continue;
if (hasSuperInitCall(MD)) {
edit::Commit commit(*Editor);
- commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER");
+ commit.insert(IFaceM->getEndLoc(), " NS_DESIGNATED_INITIALIZER");
Editor->commit(commit);
}
}
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp
index 40c8a070f813..6146e07b1d2a 100644
--- a/lib/ARCMigrate/TransAPIUses.cpp
+++ b/lib/ARCMigrate/TransAPIUses.cpp
@@ -75,7 +75,7 @@ public:
return true;
if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone)
- Pass.TA.report(parm->getLocStart(),
+ Pass.TA.report(parm->getBeginLoc(),
diag::err_arcmt_nsinvocation_ownership,
parm->getSourceRange())
<< selName;
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
index 2d35655d186f..9d20774a89a6 100644
--- a/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -128,21 +128,21 @@ public:
Pass.TA.removeStmt(*scope.End);
Stmt::child_iterator retI = scope.End;
++retI;
- SourceLocation afterSemi = findLocationAfterSemi((*retI)->getLocEnd(),
- Pass.Ctx);
+ SourceLocation afterSemi =
+ findLocationAfterSemi((*retI)->getEndLoc(), Pass.Ctx);
assert(afterSemi.isValid() &&
"Didn't we check before setting IsFollowedBySimpleReturnStmt "
"to true?");
Pass.TA.insertAfterToken(afterSemi, "\n}");
Pass.TA.increaseIndentation(
- SourceRange(scope.getIndentedRange().getBegin(),
- (*retI)->getLocEnd()),
- scope.CompoundParent->getLocStart());
+ SourceRange(scope.getIndentedRange().getBegin(),
+ (*retI)->getEndLoc()),
+ scope.CompoundParent->getBeginLoc());
} else {
Pass.TA.replaceStmt(*scope.Begin, "@autoreleasepool {");
Pass.TA.replaceStmt(*scope.End, "}");
Pass.TA.increaseIndentation(scope.getIndentedRange(),
- scope.CompoundParent->getLocStart());
+ scope.CompoundParent->getBeginLoc());
}
}
@@ -241,7 +241,7 @@ private:
Stmt::child_iterator rangeE = Begin;
for (Stmt::child_iterator I = rangeS; I != End; ++I)
++rangeE;
- return SourceRange((*rangeS)->getLocStart(), (*rangeE)->getLocEnd());
+ return SourceRange((*rangeS)->getBeginLoc(), (*rangeE)->getEndLoc());
}
};
@@ -256,8 +256,8 @@ private:
SourceLocation &declarationLoc)
: Ctx(ctx), referenceLoc(referenceLoc),
declarationLoc(declarationLoc) {
- ScopeRange = SourceRange((*scope.Begin)->getLocStart(),
- (*scope.End)->getLocStart());
+ ScopeRange = SourceRange((*scope.Begin)->getBeginLoc(),
+ (*scope.End)->getBeginLoc());
}
bool VisitDeclRefExpr(DeclRefExpr *E) {
@@ -307,7 +307,7 @@ private:
if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI))
if ((retS->getRetValue() == nullptr ||
isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) &&
- findLocationAfterSemi(retS->getLocEnd(), Pass.Ctx).isValid()) {
+ findLocationAfterSemi(retS->getEndLoc(), Pass.Ctx).isValid()) {
scope.IsFollowedBySimpleReturnStmt = true;
++SI; // the return will be included in scope, don't check it.
}
@@ -328,9 +328,9 @@ private:
"NSAutoreleasePool scope that it was declared in", referenceLoc);
Pass.TA.reportNote("name declared here", declarationLoc);
Pass.TA.reportNote("intended @autoreleasepool scope begins here",
- (*scope.Begin)->getLocStart());
+ (*scope.Begin)->getBeginLoc());
Pass.TA.reportNote("intended @autoreleasepool scope ends here",
- (*scope.End)->getLocStart());
+ (*scope.End)->getBeginLoc());
return;
}
}
@@ -403,8 +403,8 @@ private:
return cast<Expr>(getEssential((Stmt*)E));
}
static Stmt *getEssential(Stmt *S) {
- if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(S))
- S = EWC->getSubExpr();
+ if (FullExpr *FE = dyn_cast<FullExpr>(S))
+ S = FE->getSubExpr();
if (Expr *E = dyn_cast<Expr>(S))
S = E->IgnoreParenCasts();
return S;
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index fb45cd92c1f6..7697d3f048e6 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -81,10 +81,11 @@ public:
}
bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {
- if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
+ auto *OwnershipAttr = TL.getAttrAs<ObjCOwnershipAttr>();
+ if (!OwnershipAttr)
return false;
- SourceLocation Loc = TL.getAttrNameLoc();
+ SourceLocation Loc = OwnershipAttr->getLocation();
unsigned RawLoc = Loc.getRawEncoding();
if (MigrateCtx.AttrSet.count(RawLoc))
return true;
@@ -93,13 +94,7 @@ public:
SourceManager &SM = Ctx.getSourceManager();
if (Loc.isMacroID())
Loc = SM.getImmediateExpansionRange(Loc).getBegin();
- SmallString<32> Buf;
- bool Invalid = false;
- StringRef Spell = Lexer::getSpelling(
- SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),
- Buf, SM, Ctx.getLangOpts(), &Invalid);
- if (Invalid)
- return false;
+ StringRef Spell = OwnershipAttr->getKind()->getName();
MigrationContext::GCAttrOccurrence::AttrKind Kind;
if (Spell == "strong")
Kind = MigrationContext::GCAttrOccurrence::Strong;
@@ -284,7 +279,7 @@ static void checkAllAtProps(MigrationContext &MigrateCtx,
}
for (unsigned i = 0, e = ATLs.size(); i != e; ++i) {
- SourceLocation Loc = ATLs[i].first.getAttrNameLoc();
+ SourceLocation Loc = ATLs[i].first.getAttr()->getLocation();
if (Loc.isMacroID())
Loc = MigrateCtx.Pass.Ctx.getSourceManager()
.getImmediateExpansionRange(Loc)
@@ -340,7 +335,7 @@ void MigrationContext::dumpGCAttrs() {
llvm::errs() << "KIND: "
<< (Attr.Kind == GCAttrOccurrence::Strong ? "strong" : "weak");
llvm::errs() << "\nLOC: ";
- Attr.Loc.dump(Pass.Ctx.getSourceManager());
+ Attr.Loc.print(llvm::errs(), Pass.Ctx.getSourceManager());
llvm::errs() << "\nTYPE: ";
Attr.ModifiedType.dump();
if (Attr.Dcl) {
diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp
index 3a236d34cd4b..eff142ba3922 100644
--- a/lib/ARCMigrate/TransGCCalls.cpp
+++ b/lib/ARCMigrate/TransGCCalls.cpp
@@ -38,7 +38,7 @@ public:
TransformActions &TA = MigrateCtx.Pass.TA;
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
- TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc,
+ TA.report(E->getBeginLoc(), diag::warn_arcmt_nsalloc_realloc,
E->getSourceRange());
return true;
}
diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp
index 1bb4c1f4e449..bfc542e7497c 100644
--- a/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/lib/ARCMigrate/TransProtectedScope.cpp
@@ -73,12 +73,13 @@ public:
Curr = Curr->getNextSwitchCase();
}
- SourceLocation NextLoc = S->getLocEnd();
+ SourceLocation NextLoc = S->getEndLoc();
Curr = S->getSwitchCaseList();
// We iterate over case statements in reverse source-order.
while (Curr) {
- Cases.push_back(CaseInfo(Curr,SourceRange(Curr->getLocStart(), NextLoc)));
- NextLoc = Curr->getLocStart();
+ Cases.push_back(
+ CaseInfo(Curr, SourceRange(Curr->getBeginLoc(), NextLoc)));
+ NextLoc = Curr->getBeginLoc();
Curr = Curr->getNextSwitchCase();
}
return true;
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index c411044ecde3..d199bb936547 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -71,9 +71,10 @@ public:
// will likely die immediately while previously it was kept alive
// by the autorelease pool. This is bad practice in general, leave it
// and emit an error to force the user to restructure their code.
- Pass.TA.reportError("it is not safe to remove an unused 'autorelease' "
+ Pass.TA.reportError(
+ "it is not safe to remove an unused 'autorelease' "
"message; its receiver may be destroyed immediately",
- E->getLocStart(), E->getSourceRange());
+ E->getBeginLoc(), E->getSourceRange());
return true;
}
}
@@ -89,7 +90,7 @@ public:
std::string err = "it is not safe to remove '";
err += E->getSelector().getAsString() + "' message on "
"an __unsafe_unretained type";
- Pass.TA.reportError(err, rec->getLocStart());
+ Pass.TA.reportError(err, rec->getBeginLoc());
return true;
}
@@ -98,18 +99,21 @@ public:
std::string err = "it is not safe to remove '";
err += E->getSelector().getAsString() + "' message on "
"a global variable";
- Pass.TA.reportError(err, rec->getLocStart());
+ Pass.TA.reportError(err, rec->getBeginLoc());
return true;
}
if (E->getMethodFamily() == OMF_release && isDelegateMessage(rec)) {
- Pass.TA.reportError("it is not safe to remove 'retain' "
+ Pass.TA.reportError(
+ "it is not safe to remove 'retain' "
"message on the result of a 'delegate' message; "
"the object that was passed to 'setDelegate:' may not be "
- "properly retained", rec->getLocStart());
+ "properly retained",
+ rec->getBeginLoc());
return true;
}
}
+ break;
case OMF_dealloc:
break;
}
@@ -250,7 +254,7 @@ private:
}
while (OuterS && (isa<ParenExpr>(OuterS) ||
isa<CastExpr>(OuterS) ||
- isa<ExprWithCleanups>(OuterS)));
+ isa<FullExpr>(OuterS)));
if (!OuterS)
return std::make_pair(prevStmt, nextStmt);
@@ -373,8 +377,8 @@ private:
RecContainer = StmtE;
Rec = Init->IgnoreParenImpCasts();
- if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Rec))
- Rec = EWC->getSubExpr()->IgnoreParenImpCasts();
+ if (FullExpr *FE = dyn_cast<FullExpr>(Rec))
+ Rec = FE->getSubExpr()->IgnoreParenImpCasts();
RecRange = Rec->getSourceRange();
if (SM.isMacroArgExpansion(RecRange.getBegin()))
RecRange.setBegin(SM.getImmediateSpellingLoc(RecRange.getBegin()));
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 66167d37ac95..9d46d8c5fcae 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -209,7 +209,7 @@ private:
// We will remove the compiler diagnostic.
if (!TA.hasDiagnostic(diag::err_arc_mismatched_cast,
diag::err_arc_cast_requires_bridge,
- E->getLocStart())) {
+ E->getBeginLoc())) {
Trans.abort();
return;
}
@@ -225,13 +225,12 @@ private:
}
TA.clearDiagnostic(diag::err_arc_mismatched_cast,
- diag::err_arc_cast_requires_bridge,
- E->getLocStart());
+ diag::err_arc_cast_requires_bridge, E->getBeginLoc());
if (Kind == OBC_Bridge || !Pass.CFBridgingFunctionsDefined()) {
if (CStyleCastExpr *CCE = dyn_cast<CStyleCastExpr>(E)) {
TA.insertAfterToken(CCE->getLParenLoc(), bridge);
} else {
- SourceLocation insertLoc = E->getSubExpr()->getLocStart();
+ SourceLocation insertLoc = E->getSubExpr()->getBeginLoc();
SmallString<128> newCast;
newCast += '(';
newCast += bridge;
@@ -243,7 +242,7 @@ private:
} else {
newCast += '(';
TA.insert(insertLoc, newCast.str());
- TA.insertAfterToken(E->getLocEnd(), ")");
+ TA.insertAfterToken(E->getEndLoc(), ")");
}
}
} else {
@@ -251,7 +250,7 @@ private:
SmallString<32> BridgeCall;
Expr *WrapE = E->getSubExpr();
- SourceLocation InsertLoc = WrapE->getLocStart();
+ SourceLocation InsertLoc = WrapE->getBeginLoc();
SourceManager &SM = Pass.Ctx.getSourceManager();
char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1));
@@ -268,7 +267,7 @@ private:
} else {
BridgeCall += '(';
TA.insert(InsertLoc, BridgeCall);
- TA.insertAfterToken(WrapE->getLocEnd(), ")");
+ TA.insertAfterToken(WrapE->getEndLoc(), ")");
}
}
}
@@ -368,19 +367,19 @@ private:
err += family == OMF_autorelease ? "autorelease" : "release";
err += "' message; a __bridge cast may result in a pointer to a "
"destroyed object and a __bridge_retained may leak the object";
- Pass.TA.reportError(err, E->getLocStart(),
+ Pass.TA.reportError(err, E->getBeginLoc(),
E->getSubExpr()->getSourceRange());
Stmt *parent = E;
do {
parent = StmtMap->getParentIgnoreParenImpCasts(parent);
- } while (parent && isa<ExprWithCleanups>(parent));
+ } while (parent && isa<FullExpr>(parent));
if (ReturnStmt *retS = dyn_cast_or_null<ReturnStmt>(parent)) {
std::string note = "remove the cast and change return type of function "
"to '";
note += E->getSubExpr()->getType().getAsString(Pass.Ctx.getPrintingPolicy());
note += "' to have the object automatically autoreleased";
- Pass.TA.reportNote(note, retS->getLocStart());
+ Pass.TA.reportNote(note, retS->getBeginLoc());
}
}
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index 3f79cc441e85..d1768bc56cfc 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -350,7 +350,7 @@ void TransformActionsImpl::replaceText(SourceLocation loc, StringRef text,
void TransformActionsImpl::replaceStmt(Stmt *S, StringRef text) {
assert(IsInTransaction && "Actions only allowed during a transaction");
text = getUniqueText(text);
- insert(S->getLocStart(), text);
+ insert(S->getBeginLoc(), text);
removeStmt(S);
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 4a7af2858879..8bd2b407aee9 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -74,8 +74,8 @@ bool trans::isPlusOneAssign(const BinaryOperator *E) {
bool trans::isPlusOne(const Expr *E) {
if (!E)
return false;
- if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(E))
- E = EWC->getSubExpr();
+ if (const FullExpr *FE = dyn_cast<FullExpr>(E))
+ E = FE->getSubExpr();
if (const ObjCMessageExpr *
ME = dyn_cast<ObjCMessageExpr>(E->IgnoreParenCasts()))
@@ -359,7 +359,7 @@ MigrationContext::~MigrationContext() {
bool MigrationContext::isGCOwnedNonObjC(QualType T) {
while (!T.isNull()) {
if (const AttributedType *AttrT = T->getAs<AttributedType>()) {
- if (AttrT->getAttrKind() == AttributedType::attr_objc_ownership)
+ if (AttrT->getAttrKind() == attr::ObjCOwnership)
return !AttrT->getModifiedType()->isObjCRetainableType();
}
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index c45b52a65a4d..c05b160b8e3d 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -416,18 +416,26 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
<< GetApproxValue(getComplexFloatImag()) << "i";
return;
case APValue::LValue: {
- LValueBase Base = getLValueBase();
- if (!Base) {
- Out << "0";
- return;
- }
-
bool IsReference = Ty->isReferenceType();
QualType InnerTy
= IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
if (InnerTy.isNull())
InnerTy = Ty;
+ LValueBase Base = getLValueBase();
+ if (!Base) {
+ if (isNullPointer()) {
+ Out << (Ctx.getLangOpts().CPlusPlus11 ? "nullptr" : "0");
+ } else if (IsReference) {
+ Out << "*(" << InnerTy.stream(Ctx.getPrintingPolicy()) << "*)"
+ << getLValueOffset().getQuantity();
+ } else {
+ Out << "(" << Ty.stream(Ctx.getPrintingPolicy()) << ")"
+ << getLValueOffset().getQuantity();
+ }
+ return;
+ }
+
if (!hasLValuePath()) {
// No lvalue path: just print the offset.
CharUnits O = getLValueOffset();
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d50f4493788a..21b6f36e9aa7 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -48,6 +48,7 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CommentOptions.h"
#include "clang/Basic/ExceptionSpecificationType.h"
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
@@ -192,7 +193,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
isa<ObjCPropertyDecl>(D) ||
isa<RedeclarableTemplateDecl>(D) ||
isa<ClassTemplateSpecializationDecl>(D))
- DeclLoc = D->getLocStart();
+ DeclLoc = D->getBeginLoc();
else {
DeclLoc = D->getLocation();
if (DeclLoc.isMacroID()) {
@@ -200,7 +201,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// If location of the typedef name is in a macro, it is because being
// declared via a macro. Try using declaration's starting location as
// the "declaration location".
- DeclLoc = D->getLocStart();
+ DeclLoc = D->getBeginLoc();
} 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
@@ -795,11 +796,10 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
CompCategories(this_()), LastSDM(nullptr, 0) {
TUDecl = TranslationUnitDecl::Create(*this);
+ TraversalScope = {TUDecl};
}
ASTContext::~ASTContext() {
- ReleaseParentMapEntries();
-
// Release the DenseMaps associated with DeclContext objects.
// FIXME: Is this the ideal solution?
ReleaseDeclContextMaps();
@@ -837,22 +837,80 @@ ASTContext::~ASTContext() {
Value.second->~PerModuleInitializers();
}
-void ASTContext::ReleaseParentMapEntries() {
- if (!PointerParents) return;
- for (const auto &Entry : *PointerParents) {
- if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
- delete Entry.second.get<ast_type_traits::DynTypedNode *>();
- } else if (Entry.second.is<ParentVector *>()) {
- delete Entry.second.get<ParentVector *>();
+class ASTContext::ParentMap {
+ /// Contains parents of a node.
+ using ParentVector = llvm::SmallVector<ast_type_traits::DynTypedNode, 2>;
+
+ /// Maps from a node to its parents. This is used for nodes that have
+ /// pointer identity only, which are more common and we can save space by
+ /// only storing a unique pointer to them.
+ using ParentMapPointers = llvm::DenseMap<
+ const void *,
+ llvm::PointerUnion4<const Decl *, const Stmt *,
+ ast_type_traits::DynTypedNode *, ParentVector *>>;
+
+ /// Parent map for nodes without pointer identity. We store a full
+ /// DynTypedNode for all keys.
+ using ParentMapOtherNodes = llvm::DenseMap<
+ ast_type_traits::DynTypedNode,
+ llvm::PointerUnion4<const Decl *, const Stmt *,
+ ast_type_traits::DynTypedNode *, ParentVector *>>;
+
+ ParentMapPointers PointerParents;
+ ParentMapOtherNodes OtherParents;
+ class ASTVisitor;
+
+ static ast_type_traits::DynTypedNode
+ getSingleDynTypedNodeFromParentMap(ParentMapPointers::mapped_type U) {
+ if (const auto *D = U.dyn_cast<const Decl *>())
+ return ast_type_traits::DynTypedNode::create(*D);
+ if (const auto *S = U.dyn_cast<const Stmt *>())
+ return ast_type_traits::DynTypedNode::create(*S);
+ return *U.get<ast_type_traits::DynTypedNode *>();
+ }
+
+ template <typename NodeTy, typename MapTy>
+ static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
+ const MapTy &Map) {
+ auto I = Map.find(Node);
+ if (I == Map.end()) {
+ return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
+ }
+ if (const auto *V = I->second.template dyn_cast<ParentVector *>()) {
+ return llvm::makeArrayRef(*V);
+ }
+ return getSingleDynTypedNodeFromParentMap(I->second);
+ }
+
+public:
+ ParentMap(ASTContext &Ctx);
+ ~ParentMap() {
+ for (const auto &Entry : PointerParents) {
+ if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+ delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+ } else if (Entry.second.is<ParentVector *>()) {
+ delete Entry.second.get<ParentVector *>();
+ }
}
- }
- for (const auto &Entry : *OtherParents) {
- if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
- delete Entry.second.get<ast_type_traits::DynTypedNode *>();
- } else if (Entry.second.is<ParentVector *>()) {
- delete Entry.second.get<ParentVector *>();
+ for (const auto &Entry : OtherParents) {
+ if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+ delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+ } else if (Entry.second.is<ParentVector *>()) {
+ delete Entry.second.get<ParentVector *>();
+ }
}
}
+
+ DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node) {
+ if (Node.getNodeKind().hasPointerIdentity())
+ return getDynNodeFromMap(Node.getMemoizationData(), PointerParents);
+ return getDynNodeFromMap(Node, OtherParents);
+ }
+};
+
+void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
+ TraversalScope = TopLevelDecls;
+ Parents.reset();
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
@@ -885,7 +943,9 @@ void ASTContext::PrintStats() const {
#define TYPE(Name, Parent) \
if (counts[Idx]) \
llvm::errs() << " " << counts[Idx] << " " << #Name \
- << " types\n"; \
+ << " types, " << sizeof(Name##Type) << " each " \
+ << "(" << counts[Idx] * sizeof(Name##Type) \
+ << " bytes)\n"; \
TotalBytes += counts[Idx] * sizeof(Name##Type); \
++Idx;
#define ABSTRACT_TYPE(Name, Parent)
@@ -929,14 +989,11 @@ void ASTContext::mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
if (auto *Listener = getASTMutationListener())
Listener->RedefinedHiddenDefinition(ND, M);
- if (getLangOpts().ModulesLocalVisibility)
- MergedDefModules[ND].push_back(M);
- else
- ND->setVisibleDespiteOwningModule();
+ MergedDefModules[cast<NamedDecl>(ND->getCanonicalDecl())].push_back(M);
}
void ASTContext::deduplicateMergedDefinitonsFor(NamedDecl *ND) {
- auto It = MergedDefModules.find(ND);
+ auto It = MergedDefModules.find(cast<NamedDecl>(ND->getCanonicalDecl()));
if (It == MergedDefModules.end())
return;
@@ -1241,6 +1298,10 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(OCLClkEventTy, BuiltinType::OCLClkEvent);
InitBuiltinType(OCLQueueTy, BuiltinType::OCLQueue);
InitBuiltinType(OCLReserveIDTy, BuiltinType::OCLReserveID);
+
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ InitBuiltinType(Id##Ty, BuiltinType::Id);
+#include "clang/Basic/OpenCLExtensionTypes.def"
}
// Builtin type for __objc_yes and __objc_no
@@ -1892,6 +1953,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id:
+#include "clang/Basic/OpenCLExtensionTypes.def"
AS = getTargetAddressSpace(
Target->getOpenCLTypeAddrSpace(getOpenCLTypeKind(T)));
Width = Target->getPointerWidth(AS);
@@ -2295,12 +2359,11 @@ structHasUniqueObjectRepresentations(const ASTContext &Context,
}
}
- 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()) <
- Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
- });
+ llvm::sort(Bases, [&](const std::pair<QualType, int64_t> &L,
+ const std::pair<QualType, int64_t> &R) {
+ return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) <
+ Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
+ });
for (const auto Base : Bases) {
int64_t BaseOffset = Context.toBits(
@@ -2500,21 +2563,24 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
/// Get the copy initialization expression of VarDecl, or nullptr if
/// none exists.
-Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
+ASTContext::BlockVarCopyInit
+ASTContext::getBlockVarCopyInit(const VarDecl*VD) const {
assert(VD && "Passed null params");
assert(VD->hasAttr<BlocksAttr>() &&
"getBlockVarCopyInits - not __block var");
- llvm::DenseMap<const VarDecl*, Expr*>::iterator
- I = BlockVarCopyInits.find(VD);
- return (I != BlockVarCopyInits.end()) ? I->second : nullptr;
+ auto I = BlockVarCopyInits.find(VD);
+ if (I != BlockVarCopyInits.end())
+ return I->second;
+ return {nullptr, false};
}
/// Set the copy inialization expression of a block var decl.
-void ASTContext::setBlockVarCopyInits(VarDecl*VD, Expr* Init) {
- assert(VD && Init && "Passed null params");
+void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,
+ bool CanThrow) {
+ assert(VD && CopyExpr && "Passed null params");
assert(VD->hasAttr<BlocksAttr>() &&
"setBlockVarCopyInits - not __block var");
- BlockVarCopyInits[VD] = Init;
+ BlockVarCopyInits[VD].setExprAndFlag(CopyExpr, CanThrow);
}
TypeSourceInfo *ASTContext::CreateTypeSourceInfo(QualType T,
@@ -3695,30 +3761,20 @@ QualType ASTContext::getFunctionTypeInternal(
assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
- // FunctionProtoType objects are allocated with extra bytes after
- // them for three variable size arrays at the end:
- // - parameter types
- // - exception types
- // - extended parameter information
- // 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) +
- 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
- // it's much easier to skip past them compared to the elaborate switch
- // required to skip the exception specification. However, all is not
- // equal; ExtParameterInfos are used to model very uncommon features,
- // and it's better not to burden the more common paths.
- if (EPI.ExtParameterInfos) {
- Size += NumArgs * sizeof(FunctionProtoType::ExtParameterInfo);
- }
-
- auto *FTP = (FunctionProtoType *) Allocate(Size, TypeAlignment);
+ // Compute the needed size to hold this FunctionProtoType and the
+ // various trailing objects.
+ auto ESH = FunctionProtoType::getExceptionSpecSize(
+ EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size());
+ size_t Size = FunctionProtoType::totalSizeToAlloc<
+ QualType, FunctionType::FunctionTypeExtraBitfields,
+ FunctionType::ExceptionType, Expr *, FunctionDecl *,
+ FunctionProtoType::ExtParameterInfo, Qualifiers>(
+ NumArgs, FunctionProtoType::hasExtraBitfields(EPI.ExceptionSpec.Type),
+ ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr,
+ EPI.ExtParameterInfos ? NumArgs : 0,
+ EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0);
+
+ auto *FTP = (FunctionProtoType *)Allocate(Size, TypeAlignment);
FunctionProtoType::ExtProtoInfo newEPI = EPI;
new (FTP) FunctionProtoType(ResultTy, ArgArray, Canonical, newEPI);
Types.push_back(FTP);
@@ -3870,7 +3926,7 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
return QualType(newType, 0);
}
-QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
+QualType ASTContext::getAttributedType(attr::Kind attrKind,
QualType modifiedType,
QualType equivalentType) {
llvm::FoldingSetNodeID id;
@@ -4130,8 +4186,10 @@ QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
(void)CheckT;
}
- T = new (*this, TypeAlignment)
- ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
+ void *Mem = Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl),
+ TypeAlignment);
+ T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
+
Types.push_back(T);
ElaboratedTypes.InsertNode(T, InsertPos);
return QualType(T, 0);
@@ -4262,7 +4320,7 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
Arg = TemplateArgument(ArgType);
} else if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
Expr *E = new (*this) DeclRefExpr(
- NTTP, /*enclosing*/false,
+ *this, NTTP, /*enclosing*/ false,
NTTP->getType().getNonLValueExprType(*this),
Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation());
@@ -4542,8 +4600,8 @@ ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
if (!protocols.empty()) {
// Apply the protocol qualifers.
bool hasError;
- Canonical = applyObjCProtocolQualifiers(Canonical, protocols, hasError,
- true/*allowOnPointerType*/);
+ Canonical = getCanonicalType(applyObjCProtocolQualifiers(
+ Canonical, protocols, hasError, true /*allowOnPointerType*/));
assert(!hasError && "Error when apply protocol qualifier to bound type");
}
}
@@ -5098,7 +5156,7 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2) {
return true;
}
- if (getLangOpts().ObjC1) {
+ if (getLangOpts().ObjC) {
const auto *T1OPType = T1->getAs<ObjCObjectPointerType>();
const auto *T2OPType = T2->getAs<ObjCObjectPointerType>();
if (T1OPType && T2OPType) {
@@ -5762,50 +5820,86 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
}
TypedefDecl *ASTContext::getCFConstantStringDecl() const {
- if (!CFConstantStringTypeDecl) {
- assert(!CFConstantStringTagDecl &&
- "tag and typedef should be initialized together");
- CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag");
- CFConstantStringTagDecl->startDefinition();
-
- QualType FieldTypes[4];
- const char *FieldNames[4];
-
- // const int *isa;
- FieldTypes[0] = getPointerType(IntTy.withConst());
- FieldNames[0] = "isa";
- // int flags;
- FieldTypes[1] = IntTy;
- FieldNames[1] = "flags";
- // const char *str;
- FieldTypes[2] = getPointerType(CharTy.withConst());
- FieldNames[2] = "str";
- // long length;
- FieldTypes[3] = LongTy;
- FieldNames[3] = "length";
-
- // Create fields
- for (unsigned i = 0; i < 4; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTagDecl,
- SourceLocation(),
- SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/nullptr,
- /*BitWidth=*/nullptr,
- /*Mutable=*/false,
- ICIS_NoInit);
- Field->setAccess(AS_public);
- CFConstantStringTagDecl->addDecl(Field);
- }
+ if (CFConstantStringTypeDecl)
+ return CFConstantStringTypeDecl;
+
+ assert(!CFConstantStringTagDecl &&
+ "tag and typedef should be initialized together");
+ CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag");
+ CFConstantStringTagDecl->startDefinition();
- CFConstantStringTagDecl->completeDefinition();
- // This type is designed to be compatible with NSConstantString, but cannot
- // use the same name, since NSConstantString is an interface.
- auto tagType = getTagDeclType(CFConstantStringTagDecl);
- CFConstantStringTypeDecl =
- buildImplicitTypedef(tagType, "__NSConstantString");
+ struct {
+ QualType Type;
+ const char *Name;
+ } Fields[5];
+ unsigned Count = 0;
+
+ /// Objective-C ABI
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// const int *isa;
+ /// int flags;
+ /// const char *str;
+ /// long length;
+ /// } __NSConstantString;
+ ///
+ /// Swift ABI (4.1, 4.2)
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// uintptr_t _cfisa;
+ /// uintptr_t _swift_rc;
+ /// _Atomic(uint64_t) _cfinfoa;
+ /// const char *_ptr;
+ /// uint32_t _length;
+ /// } __NSConstantString;
+ ///
+ /// Swift ABI (5.0)
+ ///
+ /// typedef struct __NSConstantString_tag {
+ /// uintptr_t _cfisa;
+ /// uintptr_t _swift_rc;
+ /// _Atomic(uint64_t) _cfinfoa;
+ /// const char *_ptr;
+ /// uintptr_t _length;
+ /// } __NSConstantString;
+
+ const auto CFRuntime = getLangOpts().CFRuntime;
+ if (static_cast<unsigned>(CFRuntime) <
+ static_cast<unsigned>(LangOptions::CoreFoundationABI::Swift)) {
+ Fields[Count++] = { getPointerType(IntTy.withConst()), "isa" };
+ Fields[Count++] = { IntTy, "flags" };
+ Fields[Count++] = { getPointerType(CharTy.withConst()), "str" };
+ Fields[Count++] = { LongTy, "length" };
+ } else {
+ Fields[Count++] = { getUIntPtrType(), "_cfisa" };
+ Fields[Count++] = { getUIntPtrType(), "_swift_rc" };
+ Fields[Count++] = { getFromTargetType(Target->getUInt64Type()), "_swift_rc" };
+ Fields[Count++] = { getPointerType(CharTy.withConst()), "_ptr" };
+ if (CFRuntime == LangOptions::CoreFoundationABI::Swift4_1 ||
+ CFRuntime == LangOptions::CoreFoundationABI::Swift4_2)
+ Fields[Count++] = { IntTy, "_ptr" };
+ else
+ Fields[Count++] = { getUIntPtrType(), "_ptr" };
}
+ // Create fields
+ for (unsigned i = 0; i < Count; ++i) {
+ FieldDecl *Field =
+ FieldDecl::Create(*this, CFConstantStringTagDecl, SourceLocation(),
+ SourceLocation(), &Idents.get(Fields[i].Name),
+ Fields[i].Type, /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
+ Field->setAccess(AS_public);
+ CFConstantStringTagDecl->addDecl(Field);
+ }
+
+ CFConstantStringTagDecl->completeDefinition();
+ // This type is designed to be compatible with NSConstantString, but cannot
+ // use the same name, since NSConstantString is an interface.
+ auto tagType = getTagDeclType(CFConstantStringTagDecl);
+ CFConstantStringTypeDecl =
+ buildImplicitTypedef(tagType, "__NSConstantString");
+
return CFConstantStringTypeDecl;
}
@@ -5959,7 +6053,7 @@ LangAS ASTContext::getOpenCLTypeAddrSpace(const Type *T) const {
bool ASTContext::BlockRequiresCopying(QualType Ty,
const VarDecl *D) {
if (const CXXRecordDecl *record = Ty->getAsCXXRecordDecl()) {
- const Expr *copyExpr = getBlockVarCopyInits(D);
+ const Expr *copyExpr = getBlockVarCopyInit(D).getCopyExpr();
if (!copyExpr && record->hasTrivialDestructor()) return false;
return true;
@@ -5999,7 +6093,7 @@ bool ASTContext::BlockRequiresCopying(QualType Ty,
bool ASTContext::getByrefLifetime(QualType Ty,
Qualifiers::ObjCLifetime &LifeTime,
bool &HasByrefExtendedLayout) const {
- if (!getLangOpts().ObjC1 ||
+ if (!getLangOpts().ObjC ||
getLangOpts().getGC() != LangOptions::NonGC)
return false;
@@ -6471,6 +6565,9 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id:
+#include "clang/Basic/OpenCLExtensionTypes.def"
case BuiltinType::OCLEvent:
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
@@ -7677,7 +7774,7 @@ Qualifiers::GC ASTContext::getObjCGCAttrKind(QualType Ty) const {
if (getLangOpts().getGC() == LangOptions::NonGC)
return Qualifiers::GCNone;
- assert(getLangOpts().ObjC1);
+ assert(getLangOpts().ObjC);
Qualifiers::GC GCAttrs = Ty.getObjCGCAttr();
// Default behaviour under objective-C's gc is for ObjC pointers
@@ -8033,7 +8130,7 @@ void getIntersectionOfProtocols(ASTContext &Context,
// Also add the protocols associated with the LHS interface.
Context.CollectInheritedProtocols(LHS->getInterface(), LHSProtocolSet);
- // Add all of the protocls for the RHS.
+ // Add all of the protocols for the RHS.
llvm::SmallPtrSet<ObjCProtocolDecl *, 8> RHSProtocolSet;
// Start with the protocol qualifiers.
@@ -9384,9 +9481,11 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
// qualified with an address space.
char *End;
unsigned AddrSpace = strtoul(Str, &End, 10);
- if (End != Str && AddrSpace != 0) {
- Type = Context.getAddrSpaceQualType(Type,
- getLangASFromTargetAS(AddrSpace));
+ if (End != Str) {
+ // Note AddrSpace == 0 is not the same as an unspecified address space.
+ Type = Context.getAddrSpaceQualType(
+ Type,
+ Context.getLangASForBuiltinAddressSpace(AddrSpace));
Str = End;
}
if (c == '*')
@@ -9717,6 +9816,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
cast<FunctionDecl>(D)->getTemplateSpecializationKind() ==
TSK_ExplicitInstantiationDefinition;
+ // Implicit member function definitions, such as operator= might not be
+ // marked as template specializations, since they're not coming from a
+ // template but synthesized directly on the class.
+ IsExpInstDef |=
+ isa<CXXMethodDecl>(D) &&
+ cast<CXXMethodDecl>(D)->getParent()->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+
if (getExternalSource()->DeclIsFromPCHWithObjectFile(D) && !IsExpInstDef)
return false;
}
@@ -9766,6 +9873,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
const auto *VD = cast<VarDecl>(D);
assert(VD->isFileVarDecl() && "Expected file scoped var");
+ // If the decl is marked as `declare target to`, it should be emitted for the
+ // host and for the device.
+ if (LangOpts.OpenMP &&
+ OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
+ return true;
+
if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
!isMSStaticDataMemberInlineDefinition(VD))
return false;
@@ -9797,27 +9910,18 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
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 {
+ llvm::function_ref<void(FunctionDecl *)> Pred) const {
assert(FD->isMultiVersion() && "Only valid for multiversioned functions");
llvm::SmallDenseSet<const FunctionDecl*, 4> SeenDecls;
- FD = FD->getCanonicalDecl();
+ FD = FD->getMostRecentDecl();
for (auto *CurDecl :
FD->getDeclContext()->getRedeclContext()->lookup(FD->getDeclName())) {
- FunctionDecl *CurFD = CurDecl->getAsFunction()->getCanonicalDecl();
+ FunctionDecl *CurFD = CurDecl->getAsFunction()->getMostRecentDecl();
if (CurFD && hasSameType(CurFD->getType(), FD->getType()) &&
std::end(SeenDecls) == llvm::find(SeenDecls, CurFD)) {
SeenDecls.insert(CurFD);
@@ -10054,21 +10158,10 @@ bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
return (Size != Align || toBits(sizeChars) > MaxInlineWidthInBits);
}
-static ast_type_traits::DynTypedNode getSingleDynTypedNodeFromParentMap(
- ASTContext::ParentMapPointers::mapped_type U) {
- if (const auto *D = U.dyn_cast<const Decl *>())
- return ast_type_traits::DynTypedNode::create(*D);
- if (const auto *S = U.dyn_cast<const Stmt *>())
- return ast_type_traits::DynTypedNode::create(*S);
- return *U.get<ast_type_traits::DynTypedNode *>();
-}
-
-namespace {
-
/// Template specializations to abstract away from pointers and TypeLocs.
/// @{
template <typename T>
-ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) {
+static ast_type_traits::DynTypedNode createDynTypedNode(const T &Node) {
return ast_type_traits::DynTypedNode::create(*Node);
}
template <>
@@ -10082,160 +10175,121 @@ createDynTypedNode(const NestedNameSpecifierLoc &Node) {
}
/// @}
- /// 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
- /// traversal - there are other relationships (for example declaration context)
- /// in the AST that are better modeled by special matchers.
- ///
- /// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
- class ParentMapASTVisitor : public RecursiveASTVisitor<ParentMapASTVisitor> {
- public:
- /// Builds and returns the translation unit's parent map.
- ///
- /// The caller takes ownership of the returned \c ParentMap.
- static std::pair<ASTContext::ParentMapPointers *,
- ASTContext::ParentMapOtherNodes *>
- buildMap(TranslationUnitDecl &TU) {
- ParentMapASTVisitor Visitor(new ASTContext::ParentMapPointers,
- new ASTContext::ParentMapOtherNodes);
- Visitor.TraverseDecl(&TU);
- return std::make_pair(Visitor.Parents, Visitor.OtherParents);
- }
+/// 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
+/// traversal - there are other relationships (for example declaration context)
+/// in the AST that are better modeled by special matchers.
+///
+/// FIXME: Currently only builds up the map using \c Stmt and \c Decl nodes.
+class ASTContext::ParentMap::ASTVisitor
+ : public RecursiveASTVisitor<ASTVisitor> {
+public:
+ ASTVisitor(ParentMap &Map) : Map(Map) {}
- private:
- friend class RecursiveASTVisitor<ParentMapASTVisitor>;
+private:
+ friend class RecursiveASTVisitor<ASTVisitor>;
- using VisitorBase = RecursiveASTVisitor<ParentMapASTVisitor>;
+ using VisitorBase = RecursiveASTVisitor<ASTVisitor>;
- ParentMapASTVisitor(ASTContext::ParentMapPointers *Parents,
- ASTContext::ParentMapOtherNodes *OtherParents)
- : Parents(Parents), OtherParents(OtherParents) {}
+ bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitTemplateInstantiations() const {
- return true;
- }
+ bool shouldVisitImplicitCode() const { return true; }
- bool shouldVisitImplicitCode() const {
+ template <typename T, typename MapNodeTy, typename BaseTraverseFn,
+ typename MapTy>
+ bool TraverseNode(T Node, MapNodeTy MapNode, BaseTraverseFn BaseTraverse,
+ MapTy *Parents) {
+ if (!Node)
return true;
- }
-
- template <typename T, typename MapNodeTy, typename BaseTraverseFn,
- typename MapTy>
- bool TraverseNode(T Node, MapNodeTy MapNode,
- BaseTraverseFn BaseTraverse, MapTy *Parents) {
- if (!Node)
- return true;
- if (ParentStack.size() > 0) {
- // FIXME: Currently we add the same parent multiple times, but only
- // when no memoization data is available for the type.
- // For example when we visit all subexpressions of template
- // instantiations; this is suboptimal, but benign: the only way to
- // visit those is with hasAncestor / hasParent, and those do not create
- // new matches.
- // The plan is to enable DynTypedNode to be storable in a map or hash
- // map. The main problem there is to implement hash functions /
- // comparison operators for all types that DynTypedNode supports that
- // do not have pointer identity.
- auto &NodeOrVector = (*Parents)[MapNode];
- if (NodeOrVector.isNull()) {
- if (const auto *D = ParentStack.back().get<Decl>())
- NodeOrVector = D;
- else if (const auto *S = ParentStack.back().get<Stmt>())
- NodeOrVector = S;
- else
- NodeOrVector =
- new ast_type_traits::DynTypedNode(ParentStack.back());
- } else {
- if (!NodeOrVector.template is<ASTContext::ParentVector *>()) {
- auto *Vector = new ASTContext::ParentVector(
- 1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
- delete NodeOrVector
- .template dyn_cast<ast_type_traits::DynTypedNode *>();
- NodeOrVector = Vector;
- }
-
- auto *Vector =
- NodeOrVector.template get<ASTContext::ParentVector *>();
- // Skip duplicates for types that have memoization data.
- // We must check that the type has memoization data before calling
- // std::find() because DynTypedNode::operator== can't compare all
- // types.
- bool Found = ParentStack.back().getMemoizationData() &&
- std::find(Vector->begin(), Vector->end(),
- ParentStack.back()) != Vector->end();
- if (!Found)
- Vector->push_back(ParentStack.back());
+ if (ParentStack.size() > 0) {
+ // FIXME: Currently we add the same parent multiple times, but only
+ // when no memoization data is available for the type.
+ // For example when we visit all subexpressions of template
+ // instantiations; this is suboptimal, but benign: the only way to
+ // visit those is with hasAncestor / hasParent, and those do not create
+ // new matches.
+ // The plan is to enable DynTypedNode to be storable in a map or hash
+ // map. The main problem there is to implement hash functions /
+ // comparison operators for all types that DynTypedNode supports that
+ // do not have pointer identity.
+ auto &NodeOrVector = (*Parents)[MapNode];
+ if (NodeOrVector.isNull()) {
+ if (const auto *D = ParentStack.back().get<Decl>())
+ NodeOrVector = D;
+ else if (const auto *S = ParentStack.back().get<Stmt>())
+ NodeOrVector = S;
+ else
+ NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
+ } else {
+ if (!NodeOrVector.template is<ParentVector *>()) {
+ auto *Vector = new ParentVector(
+ 1, getSingleDynTypedNodeFromParentMap(NodeOrVector));
+ delete NodeOrVector
+ .template dyn_cast<ast_type_traits::DynTypedNode *>();
+ NodeOrVector = Vector;
}
- }
- ParentStack.push_back(createDynTypedNode(Node));
- bool Result = BaseTraverse();
- ParentStack.pop_back();
- return Result;
- }
- bool TraverseDecl(Decl *DeclNode) {
- return TraverseNode(DeclNode, DeclNode,
- [&] { return VisitorBase::TraverseDecl(DeclNode); },
- Parents);
+ auto *Vector = NodeOrVector.template get<ParentVector *>();
+ // Skip duplicates for types that have memoization data.
+ // We must check that the type has memoization data before calling
+ // std::find() because DynTypedNode::operator== can't compare all
+ // types.
+ bool Found = ParentStack.back().getMemoizationData() &&
+ std::find(Vector->begin(), Vector->end(),
+ ParentStack.back()) != Vector->end();
+ if (!Found)
+ Vector->push_back(ParentStack.back());
+ }
}
+ ParentStack.push_back(createDynTypedNode(Node));
+ bool Result = BaseTraverse();
+ ParentStack.pop_back();
+ return Result;
+ }
- bool TraverseStmt(Stmt *StmtNode) {
- return TraverseNode(StmtNode, StmtNode,
- [&] { return VisitorBase::TraverseStmt(StmtNode); },
- Parents);
- }
+ bool TraverseDecl(Decl *DeclNode) {
+ return TraverseNode(
+ DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
+ &Map.PointerParents);
+ }
- bool TraverseTypeLoc(TypeLoc TypeLocNode) {
- return TraverseNode(
- TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode),
- [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
- OtherParents);
- }
+ bool TraverseStmt(Stmt *StmtNode) {
+ return TraverseNode(
+ StmtNode, StmtNode, [&] { return VisitorBase::TraverseStmt(StmtNode); },
+ &Map.PointerParents);
+ }
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
- return TraverseNode(
- NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode),
- [&] {
- return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode);
- },
- OtherParents);
- }
+ bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+ return TraverseNode(
+ TypeLocNode, ast_type_traits::DynTypedNode::create(TypeLocNode),
+ [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
+ &Map.OtherParents);
+ }
- ASTContext::ParentMapPointers *Parents;
- ASTContext::ParentMapOtherNodes *OtherParents;
- llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
- };
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
+ return TraverseNode(
+ NNSLocNode, ast_type_traits::DynTypedNode::create(NNSLocNode),
+ [&] { return VisitorBase::TraverseNestedNameSpecifierLoc(NNSLocNode); },
+ &Map.OtherParents);
+ }
-} // namespace
+ ParentMap &Map;
+ llvm::SmallVector<ast_type_traits::DynTypedNode, 16> ParentStack;
+};
-template <typename NodeTy, typename MapTy>
-static ASTContext::DynTypedNodeList getDynNodeFromMap(const NodeTy &Node,
- const MapTy &Map) {
- auto I = Map.find(Node);
- if (I == Map.end()) {
- return llvm::ArrayRef<ast_type_traits::DynTypedNode>();
- }
- if (const auto *V =
- I->second.template dyn_cast<ASTContext::ParentVector *>()) {
- return llvm::makeArrayRef(*V);
- }
- return getSingleDynTypedNodeFromParentMap(I->second);
+ASTContext::ParentMap::ParentMap(ASTContext &Ctx) {
+ ASTVisitor(*this).TraverseAST(Ctx);
}
ASTContext::DynTypedNodeList
ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
- if (!PointerParents) {
- // We always need to run over the whole translation unit, as
+ if (!Parents)
+ // We build the parent map for the traversal scope (usually whole TU), as
// hasAncestor can escape any subtree.
- auto Maps = ParentMapASTVisitor::buildMap(*getTranslationUnitDecl());
- PointerParents.reset(Maps.first);
- OtherParents.reset(Maps.second);
- }
- if (Node.getNodeKind().hasPointerIdentity())
- return getDynNodeFromMap(Node.getMemoizationData(), *PointerParents);
- return getDynNodeFromMap(Node, *OtherParents);
+ Parents = llvm::make_unique<ParentMap>(*this);
+ return Parents->getParents(Node);
}
bool
@@ -10322,6 +10376,16 @@ QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {
}
}
+LangAS ASTContext::getLangASForBuiltinAddressSpace(unsigned AS) const {
+ if (LangOpts.OpenCL)
+ return getTargetInfo().getOpenCLBuiltinAddressSpace(AS);
+
+ if (LangOpts.CUDA)
+ return getTargetInfo().getCUDABuiltinAddressSpace(AS);
+
+ return getLangASFromTargetAS(AS);
+}
+
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
// doesn't include ASTContext.h
template
@@ -10419,3 +10483,22 @@ unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {
return 0;
}
}
+
+FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+ bool isSigned = Ty->isSignedFixedPointType();
+ return FixedPointSemantics(
+ static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned,
+ Ty->isSaturatedFixedPointType(),
+ !isSigned && getTargetInfo().doUnsignedFixedPointTypesHavePadding());
+}
+
+APFixedPoint ASTContext::getFixedPointMax(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+ return APFixedPoint::getMax(getFixedPointSemantics(Ty));
+}
+
+APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {
+ assert(Ty->isFixedPointType());
+ return APFixedPoint::getMin(getFixedPointSemantics(Ty));
+}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index 50d2d2999e51..dd0585558572 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -334,6 +334,20 @@ void clang::FormatASTNodeDiagnosticArgument(
switch (Kind) {
default: llvm_unreachable("unknown ArgumentKind");
+ case DiagnosticsEngine::ak_qual: {
+ assert(Modifier.empty() && Argument.empty() &&
+ "Invalid modifier for Qualfiers argument");
+
+ Qualifiers Q(Qualifiers::fromOpaqueValue(Val));
+ auto S = Q.getAsString();
+ if (S.empty()) {
+ OS << "unqualified";
+ NeedQuotes = false;
+ } else {
+ OS << Q.getAsString();
+ }
+ break;
+ }
case DiagnosticsEngine::ak_qualtype_pair: {
TemplateDiffTypes &TDT = *reinterpret_cast<TemplateDiffTypes*>(Val);
QualType FromType =
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 8a653ecebae3..b52ec21943e6 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -13,7 +13,9 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/Attr.h"
+#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclLookups.h"
@@ -22,6 +24,8 @@
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/LocInfoType.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TemplateArgumentVisitor.h"
+#include "clang/AST/TextNodeDumper.h"
#include "clang/AST/TypeVisitor.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Module.h"
@@ -35,177 +39,35 @@ using namespace clang::comments;
//===----------------------------------------------------------------------===//
namespace {
- // Colors used for various parts of the AST dump
- // Do not use bold yellow for any text. It is hard to read on white screens.
- struct TerminalColor {
- raw_ostream::Colors Color;
- bool Bold;
- };
+ class ASTDumper
+ : public ConstDeclVisitor<ASTDumper>,
+ public ConstStmtVisitor<ASTDumper>,
+ public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
+ public TypeVisitor<ASTDumper>,
+ public ConstAttrVisitor<ASTDumper>,
+ public ConstTemplateArgumentVisitor<ASTDumper> {
- // Red - CastColor
- // Green - TypeColor
- // Bold Green - DeclKindNameColor, UndeserializedColor
- // Yellow - AddressColor, LocationColor
- // Blue - CommentColor, NullColor, IndentColor
- // Bold Blue - AttrColor
- // Bold Magenta - StmtColor
- // Cyan - ValueKindColor, ObjectKindColor
- // Bold Cyan - ValueColor, DeclNameColor
-
- // Decl kind names (VarDecl, FunctionDecl, etc)
- static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
- // Attr names (CleanupAttr, GuardedByAttr, etc)
- static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
- // Statement names (DeclStmt, ImplicitCastExpr, etc)
- static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
- // Comment names (FullComment, ParagraphComment, TextComment, etc)
- static const TerminalColor CommentColor = { raw_ostream::BLUE, false };
-
- // Type names (int, float, etc, plus user defined types)
- static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
-
- // Pointer address
- static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
- // Source locations
- static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
-
- // lvalue/xvalue
- static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
- // bitfield/objcproperty/objcsubscript/vectorcomponent
- static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
-
- // Null statements
- static const TerminalColor NullColor = { raw_ostream::BLUE, false };
-
- // Undeserialized entities
- static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };
-
- // CastKind from CastExpr's
- static const TerminalColor CastColor = { raw_ostream::RED, false };
-
- // Value of the statement
- static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
- // Decl names
- static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
-
- // Indents ( `, -. | )
- static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
+ TextNodeDumper NodeDumper;
- class ASTDumper
- : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
- public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> {
raw_ostream &OS;
- const CommandTraits *Traits;
- const SourceManager *SM;
/// The policy to use for printing; can be defaulted.
PrintingPolicy PrintPolicy;
- /// Pending[i] is an action to dump an entity at level i.
- llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
-
/// Indicates whether we should trigger deserialization of nodes that had
/// not already been loaded.
bool Deserialize = false;
- /// Indicates whether we're at the top level.
- bool TopLevel = true;
-
- /// Indicates if we're handling the first child after entering a new depth.
- bool FirstChild = true;
-
- /// Prefix for currently-being-dumped entity.
- std::string Prefix;
-
- /// Keep track of the last location we print out so that we can
- /// print out deltas from then on out.
- const char *LastLocFilename = "";
- unsigned LastLocLine = ~0U;
-
- /// The \c FullComment parent of the comment being dumped.
- const FullComment *FC = nullptr;
-
- bool ShowColors;
+ const bool ShowColors;
/// Dump a child of the current node.
- template<typename Fn> void dumpChild(Fn doDumpChild) {
- // If we're at the top level, there's nothing interesting to do; just
- // run the dumper.
- if (TopLevel) {
- TopLevel = false;
- doDumpChild();
- while (!Pending.empty()) {
- Pending.back()(true);
- Pending.pop_back();
- }
- Prefix.clear();
- OS << "\n";
- TopLevel = true;
- return;
- }
-
- const FullComment *OrigFC = FC;
- auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) {
- // Print out the appropriate tree structure and work out the prefix for
- // children of this node. For instance:
- //
- // A Prefix = ""
- // |-B Prefix = "| "
- // | `-C Prefix = "| "
- // `-D Prefix = " "
- // |-E Prefix = " | "
- // `-F Prefix = " "
- // G Prefix = ""
- //
- // Note that the first level gets no prefix.
- {
- OS << '\n';
- ColorScope Color(*this, IndentColor);
- OS << Prefix << (isLastChild ? '`' : '|') << '-';
- this->Prefix.push_back(isLastChild ? ' ' : '|');
- this->Prefix.push_back(' ');
- }
-
- FirstChild = true;
- unsigned Depth = Pending.size();
-
- FC = OrigFC;
- doDumpChild();
-
- // If any children are left, they're the last at their nesting level.
- // Dump those ones out now.
- while (Depth < Pending.size()) {
- Pending.back()(true);
- this->Pending.pop_back();
- }
-
- // Restore the old prefix.
- this->Prefix.resize(Prefix.size() - 2);
- };
-
- if (FirstChild) {
- Pending.push_back(std::move(dumpWithIndent));
- } else {
- Pending.back()(false);
- Pending.back() = std::move(dumpWithIndent);
- }
- FirstChild = false;
+ template<typename Fn> void dumpChild(Fn DoDumpChild) {
+ NodeDumper.AddChild(DoDumpChild);
+ }
+ template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) {
+ NodeDumper.AddChild(Label, DoDumpChild);
}
-
- class ColorScope {
- ASTDumper &Dumper;
- public:
- ColorScope(ASTDumper &Dumper, TerminalColor Color)
- : Dumper(Dumper) {
- if (Dumper.ShowColors)
- Dumper.OS.changeColor(Color.Color, Color.Bold);
- }
- ~ColorScope() {
- if (Dumper.ShowColors)
- Dumper.OS.resetColor();
- }
- };
public:
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
@@ -219,40 +81,39 @@ namespace {
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM, bool ShowColors,
const PrintingPolicy &PrintPolicy)
- : OS(OS), Traits(Traits), SM(SM), PrintPolicy(PrintPolicy),
- ShowColors(ShowColors) {}
+ : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
+ PrintPolicy(PrintPolicy), ShowColors(ShowColors) {}
void setDeserialize(bool D) { Deserialize = D; }
void dumpDecl(const Decl *D);
- void dumpStmt(const Stmt *S);
- void dumpFullComment(const FullComment *C);
+ void dumpStmt(const Stmt *S, StringRef Label = {});
// Utilities
- void dumpPointer(const void *Ptr);
- void dumpSourceRange(SourceRange R);
- void dumpLocation(SourceLocation Loc);
- void dumpBareType(QualType T, bool Desugar = true);
- void dumpType(QualType T);
void dumpTypeAsChild(QualType T);
void dumpTypeAsChild(const Type *T);
- void dumpBareDeclRef(const Decl *Node);
- void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
- void dumpName(const NamedDecl *D);
- bool hasNodes(const DeclContext *DC);
void dumpDeclContext(const DeclContext *DC);
void dumpLookups(const DeclContext *DC, bool DumpDecls);
void dumpAttr(const Attr *A);
// C++ Utilities
- void dumpAccessSpecifier(AccessSpecifier AS);
void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
void dumpTemplateParameters(const TemplateParameterList *TPL);
void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
- void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
+ void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
+ const Decl *From = nullptr,
+ const char *Label = nullptr);
void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
void dumpTemplateArgument(const TemplateArgument &A,
- SourceRange R = SourceRange());
+ SourceRange R = SourceRange(),
+ const Decl *From = nullptr,
+ const char *Label = nullptr);
+ template <typename SpecializationDecl>
+ void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly);
+ template <typename TemplateDecl>
+ void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
// Objective-C utilities.
void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams);
@@ -261,6 +122,9 @@ namespace {
void VisitComplexType(const ComplexType *T) {
dumpTypeAsChild(T->getElementType());
}
+ void VisitLocInfoType(const LocInfoType *T) {
+ dumpTypeAsChild(T->getTypeSourceInfo()->getType());
+ }
void VisitPointerType(const PointerType *T) {
dumpTypeAsChild(T->getPointeeType());
}
@@ -270,92 +134,39 @@ namespace {
void VisitReferenceType(const ReferenceType *T) {
dumpTypeAsChild(T->getPointeeType());
}
- void VisitRValueReferenceType(const ReferenceType *T) {
- if (T->isSpelledAsLValue())
- OS << " written as lvalue reference";
- VisitReferenceType(T);
- }
void VisitMemberPointerType(const MemberPointerType *T) {
dumpTypeAsChild(T->getClass());
dumpTypeAsChild(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) {
- switch (T->getSizeModifier()) {
- case ArrayType::Normal: break;
- case ArrayType::Static: OS << " static"; break;
- case ArrayType::Star: OS << " *"; break;
- }
- OS << " " << T->getIndexTypeQualifiers().getAsString();
dumpTypeAsChild(T->getElementType());
}
- void VisitConstantArrayType(const ConstantArrayType *T) {
- OS << " " << T->getSize();
- VisitArrayType(T);
- }
void VisitVariableArrayType(const VariableArrayType *T) {
- OS << " ";
- dumpSourceRange(T->getBracketsRange());
VisitArrayType(T);
dumpStmt(T->getSizeExpr());
}
void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
- VisitArrayType(T);
- OS << " ";
- dumpSourceRange(T->getBracketsRange());
+ dumpTypeAsChild(T->getElementType());
dumpStmt(T->getSizeExpr());
}
void VisitDependentSizedExtVectorType(
const DependentSizedExtVectorType *T) {
- OS << " ";
- dumpLocation(T->getAttributeLoc());
dumpTypeAsChild(T->getElementType());
dumpStmt(T->getSizeExpr());
}
void VisitVectorType(const VectorType *T) {
- switch (T->getVectorKind()) {
- case VectorType::GenericVector: break;
- case VectorType::AltiVecVector: OS << " altivec"; break;
- case VectorType::AltiVecPixel: OS << " altivec pixel"; break;
- case VectorType::AltiVecBool: OS << " altivec bool"; break;
- case VectorType::NeonVector: OS << " neon"; break;
- case VectorType::NeonPolyVector: OS << " neon poly"; break;
- }
- OS << " " << T->getNumElements();
dumpTypeAsChild(T->getElementType());
}
void VisitFunctionType(const FunctionType *T) {
- auto EI = T->getExtInfo();
- if (EI.getNoReturn()) OS << " noreturn";
- if (EI.getProducesResult()) OS << " produces_result";
- if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm();
- OS << " " << FunctionType::getNameForCallConv(EI.getCC());
dumpTypeAsChild(T->getReturnType());
}
void VisitFunctionProtoType(const FunctionProtoType *T) {
- auto EPI = T->getExtProtoInfo();
- if (EPI.HasTrailingReturn) OS << " trailing_return";
- if (T->isConst()) OS << " const";
- if (T->isVolatile()) OS << " volatile";
- if (T->isRestrict()) OS << " restrict";
- switch (EPI.RefQualifier) {
- case RQ_None: break;
- case RQ_LValue: OS << " &"; break;
- case RQ_RValue: OS << " &&"; break;
- }
- // FIXME: Exception specification.
- // FIXME: Consumed parameters.
VisitFunctionType(T);
for (QualType PT : T->getParamTypes())
dumpTypeAsChild(PT);
- if (EPI.Variadic)
+ if (T->getExtProtoInfo().Variadic)
dumpChild([=] { OS << "..."; });
}
- void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
- dumpDeclRef(T->getDecl());
- }
- void VisitTypedefType(const TypedefType *T) {
- dumpDeclRef(T->getDecl());
- }
void VisitTypeOfExprType(const TypeOfExprType *T) {
dumpStmt(T->getUnderlyingExpr());
}
@@ -363,25 +174,12 @@ namespace {
dumpStmt(T->getUnderlyingExpr());
}
void VisitUnaryTransformType(const UnaryTransformType *T) {
- switch (T->getUTTKind()) {
- case UnaryTransformType::EnumUnderlyingType:
- OS << " underlying_type";
- break;
- }
dumpTypeAsChild(T->getBaseType());
}
- void VisitTagType(const TagType *T) {
- dumpDeclRef(T->getDecl());
- }
void VisitAttributedType(const AttributedType *T) {
// FIXME: AttrKind
dumpTypeAsChild(T->getModifiedType());
}
- void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
- OS << " depth " << T->getDepth() << " index " << T->getIndex();
- if (T->isParameterPack()) OS << " pack";
- dumpDeclRef(T->getDecl());
- }
void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
dumpTypeAsChild(T->getReplacedParameter());
}
@@ -390,25 +188,12 @@ namespace {
dumpTypeAsChild(T->getReplacedParameter());
dumpTemplateArgument(T->getArgumentPack());
}
- void VisitAutoType(const AutoType *T) {
- if (T->isDecltypeAuto()) OS << " decltype(auto)";
- if (!T->isDeduced())
- OS << " undeduced";
- }
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- if (T->isTypeAlias()) OS << " alias";
- OS << " "; T->getTemplateName().dump(OS);
for (auto &Arg : *T)
dumpTemplateArgument(Arg);
if (T->isTypeAlias())
dumpTypeAsChild(T->getAliasedType());
}
- void VisitInjectedClassNameType(const InjectedClassNameType *T) {
- dumpDeclRef(T->getDecl());
- }
- void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- dumpDeclRef(T->getDecl());
- }
void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
dumpTypeAsChild(T->getPointeeType());
}
@@ -422,7 +207,6 @@ namespace {
dumpTypeAsChild(T->getOriginalType());
}
void VisitPackExpansionType(const PackExpansionType *T) {
- if (auto N = T->getNumExpansions()) OS << " expansions " << *N;
if (!T->isSugared())
dumpTypeAsChild(T->getPattern());
}
@@ -450,6 +234,7 @@ namespace {
// OpenMP decls
void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
+ void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
// C++ Decls
@@ -460,12 +245,6 @@ namespace {
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
void VisitCXXRecordDecl(const CXXRecordDecl *D);
void VisitStaticAssertDecl(const StaticAssertDecl *D);
- template<typename SpecializationDecl>
- void VisitTemplateDeclSpecialization(const SpecializationDecl *D,
- bool DumpExplicitInst,
- bool DumpRefOnly);
- template<typename TemplateDecl>
- void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
void VisitClassTemplateDecl(const ClassTemplateDecl *D);
void VisitClassTemplateSpecializationDecl(
@@ -504,96 +283,47 @@ namespace {
void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
+ void Visit(const BlockDecl::Capture &C);
void VisitBlockDecl(const BlockDecl *D);
// Stmts.
- void VisitStmt(const Stmt *Node);
void VisitDeclStmt(const DeclStmt *Node);
void VisitAttributedStmt(const AttributedStmt *Node);
- void VisitLabelStmt(const LabelStmt *Node);
- void VisitGotoStmt(const GotoStmt *Node);
void VisitCXXCatchStmt(const CXXCatchStmt *Node);
void VisitCapturedStmt(const CapturedStmt *Node);
// OpenMP
+ void Visit(const OMPClause *C);
void VisitOMPExecutableDirective(const OMPExecutableDirective *Node);
// 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);
- void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *ILE);
- void VisitArrayInitIndexExpr(const ArrayInitIndexExpr *ILE);
- void VisitUnaryOperator(const UnaryOperator *Node);
- void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
- void VisitMemberExpr(const MemberExpr *Node);
- void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
- void VisitBinaryOperator(const BinaryOperator *Node);
- void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
- 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);
- void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
- void VisitCXXThisExpr(const CXXThisExpr *Node);
- void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
- void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
- void VisitCXXConstructExpr(const CXXConstructExpr *Node);
- void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
- void VisitCXXNewExpr(const CXXNewExpr *Node);
- void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
- void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
- void VisitExprWithCleanups(const ExprWithCleanups *Node);
- void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
- void dumpCXXTemporary(const CXXTemporary *Temporary);
void VisitLambdaExpr(const LambdaExpr *Node) {
- VisitExpr(Node);
dumpDecl(Node->getLambdaClass());
}
void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
- void
- VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
// ObjC
void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
- void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
- void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
- void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
- void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
- void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
- void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
- void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
- void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
- void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
// Comments.
- const char *getCommandName(unsigned CommandID);
- void dumpComment(const Comment *C);
-
- // Inline comments.
- void visitTextComment(const TextComment *C);
- void visitInlineCommandComment(const InlineCommandComment *C);
- void visitHTMLStartTagComment(const HTMLStartTagComment *C);
- void visitHTMLEndTagComment(const HTMLEndTagComment *C);
-
- // Block comments.
- void visitBlockCommandComment(const BlockCommandComment *C);
- void visitParamCommandComment(const ParamCommandComment *C);
- void visitTParamCommandComment(const TParamCommandComment *C);
- void visitVerbatimBlockComment(const VerbatimBlockComment *C);
- void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
- void visitVerbatimLineComment(const VerbatimLineComment *C);
+ void dumpComment(const Comment *C, const FullComment *FC);
+
+ void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
+ dumpStmt(TA.getAsExpr());
+ }
+ void VisitPackTemplateArgument(const TemplateArgument &TA) {
+ for (const auto &TArg : TA.pack_elements())
+ dumpTemplateArgument(TArg);
+ }
+
+// Implements Visit methods for Attrs.
+#include "clang/AST/AttrNodeTraverse.inc"
};
}
@@ -601,188 +331,31 @@ namespace {
// Utilities
//===----------------------------------------------------------------------===//
-void ASTDumper::dumpPointer(const void *Ptr) {
- ColorScope Color(*this, AddressColor);
- OS << ' ' << Ptr;
-}
-
-void ASTDumper::dumpLocation(SourceLocation Loc) {
- if (!SM)
- return;
-
- ColorScope Color(*this, LocationColor);
- SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
-
- // The general format we print out is filename:line:col, but we drop pieces
- // that haven't changed since the last loc printed.
- PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
-
- if (PLoc.isInvalid()) {
- OS << "<invalid sloc>";
- return;
- }
-
- if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
- OS << PLoc.getFilename() << ':' << PLoc.getLine()
- << ':' << PLoc.getColumn();
- LastLocFilename = PLoc.getFilename();
- LastLocLine = PLoc.getLine();
- } else if (PLoc.getLine() != LastLocLine) {
- OS << "line" << ':' << PLoc.getLine()
- << ':' << PLoc.getColumn();
- LastLocLine = PLoc.getLine();
- } else {
- OS << "col" << ':' << PLoc.getColumn();
- }
-}
-
-void ASTDumper::dumpSourceRange(SourceRange R) {
- // Can't translate locations if a SourceManager isn't available.
- if (!SM)
- return;
-
- OS << " <";
- dumpLocation(R.getBegin());
- if (R.getBegin() != R.getEnd()) {
- OS << ", ";
- dumpLocation(R.getEnd());
- }
- OS << ">";
-
- // <t2.c:123:421[blah], t2.c:412:321>
-
-}
-
-void ASTDumper::dumpBareType(QualType T, bool Desugar) {
- ColorScope Color(*this, TypeColor);
-
- SplitQualType T_split = T.split();
- OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'";
-
- if (Desugar && !T.isNull()) {
- // If the type is sugared, also dump a (shallow) desugared type.
- SplitQualType D_split = T.getSplitDesugaredType();
- if (T_split != D_split)
- OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'";
- }
-}
-
-void ASTDumper::dumpType(QualType T) {
- OS << ' ';
- dumpBareType(T);
-}
-
void ASTDumper::dumpTypeAsChild(QualType T) {
SplitQualType SQT = T.split();
if (!SQT.Quals.hasQualifiers())
return dumpTypeAsChild(SQT.Ty);
dumpChild([=] {
- OS << "QualType";
- dumpPointer(T.getAsOpaquePtr());
- OS << " ";
- dumpBareType(T, false);
- OS << " " << T.split().Quals.getAsString();
+ NodeDumper.Visit(T);
dumpTypeAsChild(T.split().Ty);
});
}
void ASTDumper::dumpTypeAsChild(const Type *T) {
dumpChild([=] {
- if (!T) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>>";
- return;
- }
- if (const LocInfoType *LIT = llvm::dyn_cast<LocInfoType>(T)) {
- {
- ColorScope Color(*this, TypeColor);
- OS << "LocInfo Type";
- }
- dumpPointer(T);
- dumpTypeAsChild(LIT->getTypeSourceInfo()->getType());
+ NodeDumper.Visit(T);
+ if (!T)
return;
- }
-
- {
- ColorScope Color(*this, TypeColor);
- OS << T->getTypeClassName() << "Type";
- }
- dumpPointer(T);
- OS << " ";
- dumpBareType(QualType(T, 0), false);
+ TypeVisitor<ASTDumper>::Visit(T);
QualType SingleStepDesugar =
T->getLocallyUnqualifiedSingleStepDesugaredType();
if (SingleStepDesugar != QualType(T, 0))
- OS << " sugar";
- if (T->isDependentType())
- OS << " dependent";
- else if (T->isInstantiationDependentType())
- OS << " instantiation_dependent";
- if (T->isVariablyModifiedType())
- OS << " variably_modified";
- if (T->containsUnexpandedParameterPack())
- OS << " contains_unexpanded_pack";
- if (T->isFromAST())
- OS << " imported";
-
- TypeVisitor<ASTDumper>::Visit(T);
-
- if (SingleStepDesugar != QualType(T, 0))
dumpTypeAsChild(SingleStepDesugar);
});
}
-void ASTDumper::dumpBareDeclRef(const Decl *D) {
- if (!D) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>>";
- return;
- }
-
- {
- ColorScope Color(*this, DeclKindNameColor);
- OS << D->getDeclKindName();
- }
- dumpPointer(D);
-
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
- ColorScope Color(*this, DeclNameColor);
- OS << " '" << ND->getDeclName() << '\'';
- }
-
- if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
- dumpType(VD->getType());
-}
-
-void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
- if (!D)
- return;
-
- dumpChild([=]{
- if (Label)
- OS << Label << ' ';
- dumpBareDeclRef(D);
- });
-}
-
-void ASTDumper::dumpName(const NamedDecl *ND) {
- if (ND->getDeclName()) {
- ColorScope Color(*this, DeclNameColor);
- OS << ' ' << ND->getNameAsString();
- }
-}
-
-bool ASTDumper::hasNodes(const DeclContext *DC) {
- if (!DC)
- return false;
-
- return DC->hasExternalLexicalStorage() ||
- (Deserialize ? DC->decls_begin() != DC->decls_end()
- : DC->noload_decls_begin() != DC->noload_decls_end());
-}
-
void ASTDumper::dumpDeclContext(const DeclContext *DC) {
if (!DC)
return;
@@ -791,8 +364,8 @@ void ASTDumper::dumpDeclContext(const DeclContext *DC) {
dumpDecl(D);
if (DC->hasExternalLexicalStorage()) {
- dumpChild([=]{
- ColorScope Color(*this, UndeserializedColor);
+ dumpChild([=] {
+ ColorScope Color(OS, ShowColors, UndeserializedColor);
OS << "<undeserialized declarations>";
});
}
@@ -801,12 +374,12 @@ void ASTDumper::dumpDeclContext(const DeclContext *DC) {
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
dumpChild([=] {
OS << "StoredDeclsMap ";
- dumpBareDeclRef(cast<Decl>(DC));
+ NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
const DeclContext *Primary = DC->getPrimaryContext();
if (Primary != DC) {
OS << " primary";
- dumpPointer(cast<Decl>(Primary));
+ NodeDumper.dumpPointer(cast<Decl>(Primary));
}
bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
@@ -821,14 +394,14 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
dumpChild([=] {
OS << "DeclarationName ";
{
- ColorScope Color(*this, DeclNameColor);
+ ColorScope Color(OS, ShowColors, DeclNameColor);
OS << '\'' << Name << '\'';
}
for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
RI != RE; ++RI) {
dumpChild([=] {
- dumpBareDeclRef(*RI);
+ NodeDumper.dumpBareDeclRef(*RI);
if ((*RI)->isHidden())
OS << " hidden";
@@ -850,7 +423,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
if (HasUndeserializedLookups) {
dumpChild([=] {
- ColorScope Color(*this, UndeserializedColor);
+ ColorScope Color(OS, ShowColors, UndeserializedColor);
OS << "<undeserialized lookups>";
});
}
@@ -859,87 +432,18 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
void ASTDumper::dumpAttr(const Attr *A) {
dumpChild([=] {
- {
- ColorScope Color(*this, AttrColor);
-
- switch (A->getKind()) {
-#define ATTR(X) case attr::X: OS << #X; break;
-#include "clang/Basic/AttrList.inc"
- }
- OS << "Attr";
- }
- dumpPointer(A);
- dumpSourceRange(A->getRange());
- if (A->isInherited())
- OS << " Inherited";
- if (A->isImplicit())
- OS << " Implicit";
-#include "clang/AST/AttrDump.inc"
+ NodeDumper.Visit(A);
+ ConstAttrVisitor<ASTDumper>::Visit(A);
});
}
-static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
-
-template<typename T>
-static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
- const T *First = D->getFirstDecl();
- if (First != D)
- OS << " first " << First;
-}
-
-template<typename T>
-static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
- const T *Prev = D->getPreviousDecl();
- if (Prev)
- OS << " prev " << Prev;
-}
-
-/// Dump the previous declaration in the redeclaration chain for a declaration,
-/// if any.
-static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
- switch (D->getKind()) {
-#define DECL(DERIVED, BASE) \
- case Decl::DERIVED: \
- return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
-#define ABSTRACT_DECL(DECL)
-#include "clang/AST/DeclNodes.inc"
- }
- llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
-}
-
//===----------------------------------------------------------------------===//
// C++ Utilities
//===----------------------------------------------------------------------===//
-void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
- switch (AS) {
- case AS_none:
- break;
- case AS_public:
- OS << "public";
- break;
- case AS_protected:
- OS << "protected";
- break;
- case AS_private:
- OS << "private";
- break;
- }
-}
-
void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
dumpChild([=] {
- OS << "CXXCtorInitializer";
- if (Init->isAnyMemberInitializer()) {
- OS << ' ';
- dumpBareDeclRef(Init->getAnyMember());
- } else if (Init->isBaseInitializer()) {
- dumpType(QualType(Init->getBaseClass(), 0));
- } else if (Init->isDelegatingInitializer()) {
- dumpType(Init->getTypeSourceInfo()->getType());
- } else {
- llvm_unreachable("Unknown initializer type");
- }
+ NodeDumper.Visit(Init);
dumpStmt(Init->getInit());
});
}
@@ -959,8 +463,9 @@ void ASTDumper::dumpTemplateArgumentListInfo(
dumpTemplateArgumentLoc(TALI[i]);
}
-void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
- dumpTemplateArgument(A.getArgument(), A.getSourceRange());
+void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
+ const Decl *From, const char *Label) {
+ dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label);
}
void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
@@ -968,49 +473,11 @@ void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
dumpTemplateArgument(TAL[i]);
}
-void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
+void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
+ const Decl *From, const char *Label) {
dumpChild([=] {
- OS << "TemplateArgument";
- if (R.isValid())
- dumpSourceRange(R);
-
- switch (A.getKind()) {
- case TemplateArgument::Null:
- OS << " null";
- break;
- case TemplateArgument::Type:
- OS << " type";
- dumpType(A.getAsType());
- break;
- case TemplateArgument::Declaration:
- OS << " decl";
- dumpDeclRef(A.getAsDecl());
- break;
- case TemplateArgument::NullPtr:
- OS << " nullptr";
- break;
- case TemplateArgument::Integral:
- OS << " integral " << A.getAsIntegral();
- break;
- case TemplateArgument::Template:
- OS << " template ";
- A.getAsTemplate().dump(OS);
- break;
- case TemplateArgument::TemplateExpansion:
- OS << " template expansion";
- A.getAsTemplateOrTemplatePattern().dump(OS);
- break;
- case TemplateArgument::Expression:
- OS << " expr";
- dumpStmt(A.getAsExpr());
- break;
- case TemplateArgument::Pack:
- OS << " pack";
- for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
- I != E; ++I)
- dumpTemplateArgument(*I);
- break;
- }
+ NodeDumper.Visit(A, R, From, Label);
+ ConstTemplateArgumentVisitor<ASTDumper>::Visit(A);
});
}
@@ -1032,46 +499,9 @@ void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
void ASTDumper::dumpDecl(const Decl *D) {
dumpChild([=] {
- if (!D) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>>";
+ NodeDumper.Visit(D);
+ if (!D)
return;
- }
-
- {
- ColorScope Color(*this, DeclKindNameColor);
- OS << D->getDeclKindName() << "Decl";
- }
- dumpPointer(D);
- if (D->getLexicalDeclContext() != D->getDeclContext())
- OS << " parent " << cast<Decl>(D->getDeclContext());
- dumpPreviousDecl(OS, D);
- dumpSourceRange(D->getSourceRange());
- OS << ' ';
- dumpLocation(D->getLocation());
- if (D->isFromASTFile())
- OS << " imported";
- if (Module *M = D->getOwningModule())
- OS << " in " << M->getFullModuleName();
- if (auto *ND = dyn_cast<NamedDecl>(D))
- for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
- const_cast<NamedDecl *>(ND)))
- dumpChild([=] { OS << "also in " << M->getFullModuleName(); });
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
- if (ND->isHidden())
- OS << " hidden";
- if (D->isImplicit())
- OS << " implicit";
- if (D->isUsed())
- OS << " used";
- else if (D->isThisDeclarationReferenced())
- OS << " referenced";
- if (D->isInvalidDecl())
- OS << " invalid";
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isConstexpr())
- OS << " constexpr";
-
ConstDeclVisitor<ASTDumper>::Visit(D);
@@ -1081,22 +511,25 @@ void ASTDumper::dumpDecl(const Decl *D) {
if (const FullComment *Comment =
D->getASTContext().getLocalCommentForDeclUncached(D))
- dumpFullComment(Comment);
+ dumpComment(Comment, Comment);
// Decls within functions are visited by the body.
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
- hasNodes(dyn_cast<DeclContext>(D)))
- dumpDeclContext(cast<DeclContext>(D));
+ if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
+ auto DC = dyn_cast<DeclContext>(D);
+ if (DC &&
+ (DC->hasExternalLexicalStorage() ||
+ (Deserialize ? DC->decls_begin() != DC->decls_end()
+ : DC->noload_decls_begin() != DC->noload_decls_end())))
+ dumpDeclContext(DC);
+ }
});
}
-void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
- dumpName(D);
-}
+void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); }
void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
- dumpName(D);
- dumpType(D->getUnderlyingType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getUnderlyingType());
if (D->isModulePrivate())
OS << " __module_private__";
dumpTypeAsChild(D->getUnderlyingType());
@@ -1109,16 +542,16 @@ void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
else
OS << " struct";
}
- dumpName(D);
+ NodeDumper.dumpName(D);
if (D->isModulePrivate())
OS << " __module_private__";
if (D->isFixed())
- dumpType(D->getIntegerType());
+ NodeDumper.dumpType(D->getIntegerType());
}
void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
OS << ' ' << D->getKindName();
- dumpName(D);
+ NodeDumper.dumpName(D);
if (D->isModulePrivate())
OS << " __module_private__";
if (D->isCompleteDefinition())
@@ -1126,23 +559,23 @@ void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
}
void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
if (const Expr *Init = D->getInitExpr())
dumpStmt(Init);
}
void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
for (auto *Child : D->chain())
- dumpDeclRef(Child);
+ NodeDumper.dumpDeclRef(Child);
}
void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
StorageClass SC = D->getStorageClass();
if (SC != SC_None)
@@ -1166,7 +599,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
if (D->isTrivial())
OS << " trivial";
- if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
+ if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
switch (EPI.ExceptionSpec.Type) {
default: break;
@@ -1179,23 +612,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
}
}
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo())
- dumpTemplateArgumentList(*FTSI->TemplateArguments);
-
- if (!D->param_begin() && D->getNumParams())
- dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
- else
- for (const ParmVarDecl *Parameter : D->parameters())
- dumpDecl(Parameter);
-
- if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
- for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
- E = C->init_end();
- I != E; ++I)
- dumpCXXCtorInitializer(*I);
-
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
if (MD->size_overridden_methods() != 0) {
auto dumpOverride = [=](const CXXMethodDecl *D) {
SplitQualType T_split = D->getType().split();
@@ -1218,13 +635,26 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
}
}
+ if (const auto *FTSI = D->getTemplateSpecializationInfo())
+ dumpTemplateArgumentList(*FTSI->TemplateArguments);
+
+ if (!D->param_begin() && D->getNumParams())
+ dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
+ else
+ for (const ParmVarDecl *Parameter : D->parameters())
+ dumpDecl(Parameter);
+
+ if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
+ for (const auto *I : C->inits())
+ dumpCXXCtorInitializer(I);
+
if (D->doesThisDeclarationHaveABody())
dumpStmt(D->getBody());
}
void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
if (D->isMutable())
OS << " mutable";
if (D->isModulePrivate())
@@ -1237,8 +667,8 @@ void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
}
void ASTDumper::VisitVarDecl(const VarDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
StorageClass SC = D->getStorageClass();
if (SC != SC_None)
OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
@@ -1272,8 +702,8 @@ void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) {
}
void ASTDumper::VisitBindingDecl(const BindingDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
if (auto *E = D->getBinding())
dumpStmt(E);
}
@@ -1320,12 +750,13 @@ void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
}
void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
OS << " combiner";
- dumpStmt(D->getCombiner());
- if (auto *Initializer = D->getInitializer()) {
+ NodeDumper.dumpPointer(D->getCombiner());
+ if (const auto *Initializer = D->getInitializer()) {
OS << " initializer";
+ NodeDumper.dumpPointer(Initializer);
switch (D->getInitializerKind()) {
case OMPDeclareReductionDecl::DirectInit:
OS << " omp_priv = ";
@@ -1336,13 +767,36 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
case OMPDeclareReductionDecl::CallInit:
break;
}
+ }
+
+ dumpStmt(D->getCombiner());
+ if (const auto *Initializer = D->getInitializer())
dumpStmt(Initializer);
+}
+
+void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
+ for (auto *C : D->clauselists()) {
+ dumpChild([=] {
+ if (!C) {
+ ColorScope Color(OS, ShowColors, NullColor);
+ OS << "<<<NULL>>> OMPClause";
+ return;
+ }
+ {
+ ColorScope Color(OS, ShowColors, AttrColor);
+ StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
+ OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
+ << ClauseName.drop_front() << "Clause";
+ }
+ NodeDumper.dumpPointer(C);
+ NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
+ });
}
}
void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
dumpStmt(D->getInit());
}
@@ -1351,31 +805,31 @@ void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
//===----------------------------------------------------------------------===//
void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
- dumpName(D);
+ NodeDumper.dumpName(D);
if (D->isInline())
OS << " inline";
if (!D->isOriginalNamespace())
- dumpDeclRef(D->getOriginalNamespace(), "original");
+ NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original");
}
void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
OS << ' ';
- dumpBareDeclRef(D->getNominatedNamespace());
+ NodeDumper.dumpBareDeclRef(D->getNominatedNamespace());
}
void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- dumpName(D);
- dumpDeclRef(D->getAliasedNamespace());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getAliasedNamespace());
}
void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
- dumpName(D);
- dumpType(D->getUnderlyingType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getUnderlyingType());
dumpTypeAsChild(D->getUnderlyingType());
}
void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
- dumpName(D);
+ NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
dumpDecl(D->getTemplatedDecl());
}
@@ -1387,7 +841,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "DefinitionData";
}
#define FLAG(fn, name) if (D->fn()) OS << " " #name;
@@ -1415,7 +869,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "DefaultConstructor";
}
FLAG(hasDefaultConstructor, exists);
@@ -1429,7 +883,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "CopyConstructor";
}
FLAG(hasSimpleCopyConstructor, simple);
@@ -1447,7 +901,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "MoveConstructor";
}
FLAG(hasMoveConstructor, exists);
@@ -1464,7 +918,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "CopyAssignment";
}
FLAG(hasTrivialCopyAssignment, trivial);
@@ -1478,7 +932,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "MoveAssignment";
}
FLAG(hasMoveAssignment, exists);
@@ -1492,7 +946,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
{
- ColorScope Color(*this, DeclKindNameColor);
+ ColorScope Color(OS, ShowColors, DeclKindNameColor);
OS << "Destructor";
}
FLAG(hasSimpleDestructor, simple);
@@ -1511,8 +965,8 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
dumpChild([=] {
if (I.isVirtual())
OS << "virtual ";
- dumpAccessSpecifier(I.getAccessSpecifier());
- dumpType(I.getType());
+ NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier());
+ NodeDumper.dumpType(I.getType());
if (I.isPackExpansion())
OS << "...";
});
@@ -1524,10 +978,10 @@ void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
dumpStmt(D->getMessage());
}
-template<typename SpecializationDecl>
-void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
- bool DumpExplicitInst,
- bool DumpRefOnly) {
+template <typename SpecializationDecl>
+void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly) {
bool DumpedAny = false;
for (auto *RedeclWithBadType : D->redecls()) {
// FIXME: The redecls() range sometimes has elements of a less-specific
@@ -1551,7 +1005,7 @@ void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
case TSK_Undeclared:
case TSK_ImplicitInstantiation:
if (DumpRefOnly)
- dumpDeclRef(Redecl);
+ NodeDumper.dumpDeclRef(Redecl);
else
dumpDecl(Redecl);
DumpedAny = true;
@@ -1563,31 +1017,30 @@ void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
// Ensure we dump at least one decl for each specialization.
if (!DumpedAny)
- dumpDeclRef(D);
+ NodeDumper.dumpDeclRef(D);
}
-template<typename TemplateDecl>
-void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
- bool DumpExplicitInst) {
- dumpName(D);
+template <typename TemplateDecl>
+void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
+ NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
dumpDecl(D->getTemplatedDecl());
for (auto *Child : D->specializations())
- VisitTemplateDeclSpecialization(Child, DumpExplicitInst,
- !D->isCanonicalDecl());
+ dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
+ !D->isCanonicalDecl());
}
void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
// FIXME: We don't add a declaration of a function template specialization
// to its context when it's explicitly instantiated, so dump explicit
// instantiations when we dump the template itself.
- VisitTemplateDecl(D, true);
+ dumpTemplateDecl(D, true);
}
void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
- VisitTemplateDecl(D, false);
+ dumpTemplateDecl(D, false);
}
void ASTDumper::VisitClassTemplateSpecializationDecl(
@@ -1610,11 +1063,11 @@ void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
}
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
- VisitTemplateDecl(D, false);
+ dumpTemplateDecl(D, false);
}
void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
- dumpName(D);
+ NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
}
@@ -1638,19 +1091,25 @@ void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
OS << " depth " << D->getDepth() << " index " << D->getIndex();
if (D->isParameterPack())
OS << " ...";
- dumpName(D);
+ NodeDumper.dumpName(D);
if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument());
+ dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
+ D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from"
+ : "previous");
}
void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
- dumpType(D->getType());
+ NodeDumper.dumpType(D->getType());
OS << " depth " << D->getDepth() << " index " << D->getIndex();
if (D->isParameterPack())
OS << " ...";
- dumpName(D);
+ NodeDumper.dumpName(D);
if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument());
+ dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
+ D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from"
+ : "previous");
}
void ASTDumper::VisitTemplateTemplateParmDecl(
@@ -1658,10 +1117,12 @@ void ASTDumper::VisitTemplateTemplateParmDecl(
OS << " depth " << D->getDepth() << " index " << D->getIndex();
if (D->isParameterPack())
OS << " ...";
- dumpName(D);
+ NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
if (D->hasDefaultArgument())
- dumpTemplateArgumentLoc(D->getDefaultArgument());
+ dumpTemplateArgumentLoc(
+ D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
+ D->defaultArgumentWasInherited() ? "inherited from" : "previous");
}
void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
@@ -1684,12 +1145,12 @@ void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D)
if (D->getQualifier())
D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getNameAsString();
- dumpType(D->getType());
+ NodeDumper.dumpType(D->getType());
}
void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
OS << ' ';
- dumpBareDeclRef(D->getTargetDecl());
+ NodeDumper.dumpBareDeclRef(D->getTargetDecl());
if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
dumpTypeAsChild(TD->getTypeForDecl());
}
@@ -1701,21 +1162,21 @@ void ASTDumper::VisitConstructorUsingShadowDecl(
dumpChild([=] {
OS << "target ";
- dumpBareDeclRef(D->getTargetDecl());
+ NodeDumper.dumpBareDeclRef(D->getTargetDecl());
});
dumpChild([=] {
OS << "nominated ";
- dumpBareDeclRef(D->getNominatedBaseClass());
+ NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass());
OS << ' ';
- dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
+ NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
});
dumpChild([=] {
OS << "constructed ";
- dumpBareDeclRef(D->getConstructedBaseClass());
+ NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass());
OS << ' ';
- dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
+ NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
});
}
@@ -1728,12 +1189,12 @@ void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
OS << ' ';
- dumpAccessSpecifier(D->getAccess());
+ NodeDumper.dumpAccessSpecifier(D->getAccess());
}
void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
if (TypeSourceInfo *T = D->getFriendType())
- dumpType(T->getType());
+ NodeDumper.dumpType(T->getType());
else
dumpDecl(D->getFriendDecl());
}
@@ -1743,8 +1204,8 @@ void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
//===----------------------------------------------------------------------===//
void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
if (D->getSynthesize())
OS << " synthesize";
@@ -1772,8 +1233,8 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
OS << " -";
else
OS << " +";
- dumpName(D);
- dumpType(D->getReturnType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getReturnType());
if (D->isThisDeclarationADefinition()) {
dumpDeclContext(D);
@@ -1790,7 +1251,7 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
}
void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
- dumpName(D);
+ NodeDumper.dumpName(D);
switch (D->getVariance()) {
case ObjCTypeParamVariance::Invariant:
break;
@@ -1806,47 +1267,47 @@ void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
if (D->hasExplicitBound())
OS << " bounded";
- dumpType(D->getUnderlyingType());
+ NodeDumper.dumpType(D->getUnderlyingType());
}
void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
- dumpName(D);
- dumpDeclRef(D->getClassInterface());
- dumpObjCTypeParamList(D->getTypeParamList());
- dumpDeclRef(D->getImplementation());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getClassInterface());
+ NodeDumper.dumpDeclRef(D->getImplementation());
for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
E = D->protocol_end();
I != E; ++I)
- dumpDeclRef(*I);
+ NodeDumper.dumpDeclRef(*I);
+ dumpObjCTypeParamList(D->getTypeParamList());
}
void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
- dumpName(D);
- dumpDeclRef(D->getClassInterface());
- dumpDeclRef(D->getCategoryDecl());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getClassInterface());
+ NodeDumper.dumpDeclRef(D->getCategoryDecl());
}
void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
- dumpName(D);
+ NodeDumper.dumpName(D);
for (auto *Child : D->protocols())
- dumpDeclRef(Child);
+ NodeDumper.dumpDeclRef(Child);
}
void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
- dumpName(D);
- dumpObjCTypeParamList(D->getTypeParamListAsWritten());
- dumpDeclRef(D->getSuperClass(), "super");
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
- dumpDeclRef(D->getImplementation());
+ NodeDumper.dumpDeclRef(D->getImplementation());
for (auto *Child : D->protocols())
- dumpDeclRef(Child);
+ NodeDumper.dumpDeclRef(Child);
+ dumpObjCTypeParamList(D->getTypeParamListAsWritten());
}
void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
- dumpName(D);
- dumpDeclRef(D->getSuperClass(), "super");
- dumpDeclRef(D->getClassInterface());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
+ NodeDumper.dumpDeclRef(D->getClassInterface());
for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
E = D->init_end();
I != E; ++I)
@@ -1854,13 +1315,13 @@ void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
}
void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
- dumpName(D);
- dumpDeclRef(D->getClassInterface());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpDeclRef(D->getClassInterface());
}
void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
- dumpName(D);
- dumpType(D->getType());
+ NodeDumper.dumpName(D);
+ NodeDumper.dumpType(D->getType());
if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
OS << " required";
@@ -1892,20 +1353,28 @@ void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
OS << " class";
if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
- dumpDeclRef(D->getGetterMethodDecl(), "getter");
+ NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter");
if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
- dumpDeclRef(D->getSetterMethodDecl(), "setter");
+ NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter");
}
}
void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
- dumpName(D->getPropertyDecl());
+ NodeDumper.dumpName(D->getPropertyDecl());
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
OS << " synthesize";
else
OS << " dynamic";
- dumpDeclRef(D->getPropertyDecl());
- dumpDeclRef(D->getPropertyIvarDecl());
+ NodeDumper.dumpDeclRef(D->getPropertyDecl());
+ NodeDumper.dumpDeclRef(D->getPropertyIvarDecl());
+}
+
+void ASTDumper::Visit(const BlockDecl::Capture &C) {
+ dumpChild([=] {
+ NodeDumper.Visit(C);
+ if (C.hasCopyExpr())
+ dumpStmt(C.getCopyExpr());
+ });
}
void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
@@ -1918,21 +1387,8 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
if (D->capturesCXXThis())
dumpChild([=]{ OS << "capture this"; });
- for (const auto &I : D->captures()) {
- dumpChild([=] {
- OS << "capture";
- if (I.isByRef())
- OS << " byref";
- if (I.isNested())
- OS << " nested";
- if (I.getVariable()) {
- OS << ' ';
- dumpBareDeclRef(I.getVariable());
- }
- if (I.hasCopyExpr())
- dumpStmt(I.getCopyExpr());
- });
- }
+ for (const auto &I : D->captures())
+ Visit(I);
dumpStmt(D->getBody());
}
@@ -1940,42 +1396,27 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
// Stmt dumping methods.
//===----------------------------------------------------------------------===//
-void ASTDumper::dumpStmt(const Stmt *S) {
- dumpChild([=] {
+void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) {
+ dumpChild(Label, [=] {
+ NodeDumper.Visit(S);
+
if (!S) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>>";
return;
}
+ ConstStmtVisitor<ASTDumper>::Visit(S);
+
// 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);
+ if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
return;
}
- ConstStmtVisitor<ASTDumper>::Visit(S);
-
for (const Stmt *SubStmt : S->children())
dumpStmt(SubStmt);
});
}
-void ASTDumper::VisitStmt(const Stmt *Node) {
- {
- ColorScope Color(*this, StmtColor);
- OS << Node->getStmtClassName();
- }
- dumpPointer(Node);
- dumpSourceRange(Node->getSourceRange());
-}
-
void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
- VisitStmt(Node);
for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
E = Node->decl_end();
I != E; ++I)
@@ -1983,31 +1424,17 @@ void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
}
void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
- VisitStmt(Node);
for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
E = Node->getAttrs().end();
I != E; ++I)
dumpAttr(*I);
}
-void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
- VisitStmt(Node);
- OS << " '" << Node->getName() << "'";
-}
-
-void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
- VisitStmt(Node);
- OS << " '" << Node->getLabel()->getName() << "'";
- dumpPointer(Node->getLabel());
-}
-
void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
- VisitStmt(Node);
dumpDecl(Node->getExceptionDecl());
}
void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
- VisitStmt(Node);
dumpDecl(Node->getCapturedDecl());
}
@@ -2015,287 +1442,41 @@ void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
// OpenMP dumping methods.
//===----------------------------------------------------------------------===//
+void ASTDumper::Visit(const OMPClause *C) {
+ dumpChild([=] {
+ NodeDumper.Visit(C);
+ for (auto *S : C->children())
+ dumpStmt(S);
+ });
+}
+
void ASTDumper::VisitOMPExecutableDirective(
const OMPExecutableDirective *Node) {
- VisitStmt(Node);
- for (auto *C : Node->clauses()) {
- dumpChild([=] {
- if (!C) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>> OMPClause";
- return;
- }
- {
- ColorScope Color(*this, AttrColor);
- StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
- OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
- << ClauseName.drop_front() << "Clause";
- }
- dumpPointer(C);
- dumpSourceRange(SourceRange(C->getLocStart(), C->getLocEnd()));
- if (C->isImplicit())
- OS << " <implicit>";
- for (auto *S : C->children())
- dumpStmt(S);
- });
- }
+ for (const auto *C : Node->clauses())
+ Visit(C);
}
//===----------------------------------------------------------------------===//
// Expr dumping methods.
//===----------------------------------------------------------------------===//
-void ASTDumper::VisitExpr(const Expr *Node) {
- VisitStmt(Node);
- dumpType(Node->getType());
-
- {
- ColorScope Color(*this, ValueKindColor);
- switch (Node->getValueKind()) {
- case VK_RValue:
- break;
- case VK_LValue:
- OS << " lvalue";
- break;
- case VK_XValue:
- OS << " xvalue";
- break;
- }
- }
-
- {
- ColorScope Color(*this, ObjectKindColor);
- switch (Node->getObjectKind()) {
- case OK_Ordinary:
- break;
- case OK_BitField:
- OS << " bitfield";
- break;
- case OK_ObjCProperty:
- OS << " objcproperty";
- break;
- case OK_ObjCSubscript:
- OS << " objcsubscript";
- break;
- case OK_VectorComponent:
- OS << " vectorcomponent";
- break;
- }
- }
-}
-
-static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
- if (Node->path_empty())
- return;
-
- OS << " (";
- bool First = true;
- for (CastExpr::path_const_iterator I = Node->path_begin(),
- E = Node->path_end();
- I != E; ++I) {
- const CXXBaseSpecifier *Base = *I;
- if (!First)
- OS << " -> ";
-
- const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
-
- if (Base->isVirtual())
- OS << "virtual ";
- OS << RD->getName();
- First = false;
- }
-
- OS << ')';
-}
-
-void ASTDumper::VisitCastExpr(const CastExpr *Node) {
- VisitExpr(Node);
- OS << " <";
- {
- ColorScope Color(*this, CastColor);
- OS << Node->getCastKindName();
- }
- dumpBasePath(OS, 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);
-
- OS << " ";
- dumpBareDeclRef(Node->getDecl());
- if (Node->getDecl() != Node->getFoundDecl()) {
- OS << " (";
- dumpBareDeclRef(Node->getFoundDecl());
- OS << ")";
- }
-}
-
-void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
- VisitExpr(Node);
- OS << " (";
- if (!Node->requiresADL())
- OS << "no ";
- OS << "ADL) = '" << Node->getName() << '\'';
-
- UnresolvedLookupExpr::decls_iterator
- I = Node->decls_begin(), E = Node->decls_end();
- if (I == E)
- OS << " empty";
- for (; I != E; ++I)
- dumpPointer(*I);
-}
-
-void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
- VisitExpr(Node);
-
- {
- ColorScope Color(*this, DeclKindNameColor);
- OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
- }
- OS << "='" << *Node->getDecl() << "'";
- dumpPointer(Node->getDecl());
- if (Node->isFreeIvar())
- OS << " isFreeIvar";
-}
-
-void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
- VisitExpr(Node);
- OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType());
-}
-
-void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
- VisitExpr(Node);
- ColorScope Color(*this, ValueColor);
- OS << " " << Node->getValue();
-}
-
-void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
- VisitExpr(Node);
-
- bool isSigned = Node->getType()->isSignedIntegerType();
- ColorScope Color(*this, ValueColor);
- 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);
- OS << " " << Node->getValueAsApproximateDouble();
-}
-
-void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
- VisitExpr(Str);
- ColorScope Color(*this, ValueColor);
- OS << " ";
- Str->outputString(OS);
-}
void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
- VisitExpr(ILE);
if (auto *Filler = ILE->getArrayFiller()) {
- dumpChild([=] {
- OS << "array filler";
- dumpStmt(Filler);
- });
- }
- if (auto *Field = ILE->getInitializedFieldInUnion()) {
- OS << " field ";
- dumpBareDeclRef(Field);
- }
-}
-
-void ASTDumper::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) {
- VisitExpr(E);
-}
-
-void ASTDumper::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) {
- VisitExpr(E);
-}
-
-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(
- const UnaryExprOrTypeTraitExpr *Node) {
- VisitExpr(Node);
- switch(Node->getKind()) {
- case UETT_SizeOf:
- OS << " sizeof";
- break;
- case UETT_AlignOf:
- OS << " alignof";
- break;
- case UETT_VecStep:
- OS << " vec_step";
- break;
- case UETT_OpenMPRequiredSimdAlign:
- OS << " __builtin_omp_required_simd_align";
- break;
+ dumpStmt(Filler, "array_filler");
}
- if (Node->isArgumentType())
- dumpType(Node->getArgumentType());
-}
-
-void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
- VisitExpr(Node);
- OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
- dumpPointer(Node->getMemberDecl());
-}
-
-void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
- VisitExpr(Node);
- OS << " " << Node->getAccessor().getNameStart();
-}
-
-void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
- VisitExpr(Node);
- OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
-}
-
-void ASTDumper::VisitCompoundAssignOperator(
- const CompoundAssignOperator *Node) {
- VisitExpr(Node);
- OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
- << "' ComputeLHSTy=";
- dumpBareType(Node->getComputationLHSType());
- OS << " ComputeResultTy=";
- dumpBareType(Node->getComputationResultType());
}
void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
- VisitExpr(Node);
dumpDecl(Node->getBlockDecl());
}
void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
- VisitExpr(Node);
-
if (Expr *Source = Node->getSourceExpr())
dumpStmt(Source);
}
void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
- VisitExpr(E);
if (E->isResultDependent())
OS << " result_dependent";
dumpStmt(E->getControllingExpr());
@@ -2305,7 +1486,7 @@ void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
dumpChild([=] {
if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
OS << "case ";
- dumpType(TSI->getType());
+ NodeDumper.dumpType(TSI->getType());
} else {
OS << "default";
}
@@ -2320,394 +1501,42 @@ void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
}
}
-// GNU extensions.
-
-void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
- VisitExpr(Node);
- OS << " " << Node->getLabel()->getName();
- dumpPointer(Node->getLabel());
-}
-
//===----------------------------------------------------------------------===//
// C++ Expressions
//===----------------------------------------------------------------------===//
-void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
- VisitExpr(Node);
- OS << " " << Node->getCastName()
- << "<" << Node->getTypeAsWritten().getAsString() << ">"
- << " <" << Node->getCastKindName();
- dumpBasePath(OS, Node);
- OS << ">";
-}
-
-void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
- VisitExpr(Node);
- OS << " " << (Node->getValue() ? "true" : "false");
-}
-
-void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
- VisitExpr(Node);
- OS << " this";
-}
-
-void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
- VisitExpr(Node);
- OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
- << " <" << Node->getCastKindName() << ">";
-}
-
-void ASTDumper::VisitCXXUnresolvedConstructExpr(
- const CXXUnresolvedConstructExpr *Node) {
- VisitExpr(Node);
- dumpType(Node->getTypeAsWritten());
- if (Node->isListInitialization())
- OS << " list";
-}
-
-void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
- VisitExpr(Node);
- CXXConstructorDecl *Ctor = Node->getConstructor();
- dumpType(Ctor->getType());
- if (Node->isElidable())
- OS << " elidable";
- if (Node->isListInitialization())
- OS << " list";
- if (Node->isStdInitListInitialization())
- OS << " std::initializer_list";
- if (Node->requiresZeroInitialization())
- OS << " zeroing";
-}
-
-void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
- VisitExpr(Node);
- OS << " ";
- dumpCXXTemporary(Node->getTemporary());
-}
-
-void ASTDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
- VisitExpr(Node);
- if (Node->isGlobalNew())
- OS << " global";
- if (Node->isArray())
- OS << " array";
- if (Node->getOperatorNew()) {
- OS << ' ';
- dumpBareDeclRef(Node->getOperatorNew());
- }
- // We could dump the deallocation function used in case of error, but it's
- // usually not that interesting.
-}
-
-void ASTDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
- VisitExpr(Node);
- if (Node->isGlobalDelete())
- OS << " global";
- if (Node->isArrayForm())
- OS << " array";
- if (Node->getOperatorDelete()) {
- OS << ' ';
- dumpBareDeclRef(Node->getOperatorDelete());
- }
-}
-
-void
-ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
- VisitExpr(Node);
- if (const ValueDecl *VD = Node->getExtendingDecl()) {
- OS << " extended by ";
- dumpBareDeclRef(VD);
- }
-}
-
-void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
- VisitExpr(Node);
- for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
- dumpDeclRef(Node->getObject(i), "cleanup");
-}
-
-void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
- OS << "(CXXTemporary";
- dumpPointer(Temporary);
- OS << ")";
-}
-
void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
- VisitExpr(Node);
- dumpPointer(Node->getPack());
- dumpName(Node->getPack());
if (Node->isPartiallySubstituted())
for (const auto &A : Node->getPartialArguments())
dumpTemplateArgument(A);
}
-void ASTDumper::VisitCXXDependentScopeMemberExpr(
- const CXXDependentScopeMemberExpr *Node) {
- VisitExpr(Node);
- OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember();
-}
-
//===----------------------------------------------------------------------===//
// Obj-C Expressions
//===----------------------------------------------------------------------===//
-void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
- VisitExpr(Node);
- OS << " selector=";
- Node->getSelector().print(OS);
- switch (Node->getReceiverKind()) {
- case ObjCMessageExpr::Instance:
- break;
-
- case ObjCMessageExpr::Class:
- OS << " class=";
- dumpBareType(Node->getClassReceiver());
- break;
-
- case ObjCMessageExpr::SuperInstance:
- OS << " super (instance)";
- break;
-
- case ObjCMessageExpr::SuperClass:
- OS << " super (class)";
- break;
- }
-}
-
-void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
- VisitExpr(Node);
- if (auto *BoxingMethod = Node->getBoxingMethod()) {
- OS << " selector=";
- BoxingMethod->getSelector().print(OS);
- }
-}
-
void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
- VisitStmt(Node);
if (const VarDecl *CatchParam = Node->getCatchParamDecl())
dumpDecl(CatchParam);
- else
- OS << " catch all";
-}
-
-void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
- VisitExpr(Node);
- dumpType(Node->getEncodedType());
-}
-
-void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
- VisitExpr(Node);
-
- OS << " ";
- Node->getSelector().print(OS);
-}
-
-void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
- VisitExpr(Node);
-
- OS << ' ' << *Node->getProtocol();
-}
-
-void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
- VisitExpr(Node);
- if (Node->isImplicitProperty()) {
- OS << " Kind=MethodRef Getter=\"";
- if (Node->getImplicitPropertyGetter())
- Node->getImplicitPropertyGetter()->getSelector().print(OS);
- else
- OS << "(null)";
-
- OS << "\" Setter=\"";
- if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
- Setter->getSelector().print(OS);
- else
- OS << "(null)";
- OS << "\"";
- } else {
- OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
- }
-
- if (Node->isSuperReceiver())
- OS << " super";
-
- OS << " Messaging=";
- if (Node->isMessagingGetter() && Node->isMessagingSetter())
- OS << "Getter&Setter";
- else if (Node->isMessagingGetter())
- OS << "Getter";
- else if (Node->isMessagingSetter())
- OS << "Setter";
-}
-
-void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
- VisitExpr(Node);
- if (Node->isArraySubscriptRefExpr())
- OS << " Kind=ArraySubscript GetterForArray=\"";
- else
- OS << " Kind=DictionarySubscript GetterForDictionary=\"";
- if (Node->getAtIndexMethodDecl())
- Node->getAtIndexMethodDecl()->getSelector().print(OS);
- else
- OS << "(null)";
-
- if (Node->isArraySubscriptRefExpr())
- OS << "\" SetterForArray=\"";
- else
- OS << "\" SetterForDictionary=\"";
- if (Node->setAtIndexMethodDecl())
- Node->setAtIndexMethodDecl()->getSelector().print(OS);
- else
- OS << "(null)";
-}
-
-void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
- VisitExpr(Node);
- OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
}
//===----------------------------------------------------------------------===//
// Comments
//===----------------------------------------------------------------------===//
-const char *ASTDumper::getCommandName(unsigned CommandID) {
- if (Traits)
- return Traits->getCommandInfo(CommandID)->Name;
- const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
- if (Info)
- return Info->Name;
- return "<not a builtin command>";
-}
-
-void ASTDumper::dumpFullComment(const FullComment *C) {
- if (!C)
- return;
-
- FC = C;
- dumpComment(C);
- FC = nullptr;
-}
-
-void ASTDumper::dumpComment(const Comment *C) {
+void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) {
dumpChild([=] {
+ NodeDumper.Visit(C, FC);
if (!C) {
- ColorScope Color(*this, NullColor);
- OS << "<<<NULL>>>";
return;
}
-
- {
- ColorScope Color(*this, CommentColor);
- OS << C->getCommentKindName();
- }
- dumpPointer(C);
- dumpSourceRange(C->getSourceRange());
- ConstCommentVisitor<ASTDumper>::visit(C);
+ ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC);
for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
I != E; ++I)
- dumpComment(*I);
+ dumpComment(*I, FC);
});
}
-void ASTDumper::visitTextComment(const TextComment *C) {
- OS << " Text=\"" << C->getText() << "\"";
-}
-
-void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
- OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
- switch (C->getRenderKind()) {
- case InlineCommandComment::RenderNormal:
- OS << " RenderNormal";
- break;
- case InlineCommandComment::RenderBold:
- OS << " RenderBold";
- break;
- case InlineCommandComment::RenderMonospaced:
- OS << " RenderMonospaced";
- break;
- case InlineCommandComment::RenderEmphasized:
- OS << " RenderEmphasized";
- break;
- }
-
- for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
- OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
-}
-
-void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
- OS << " Name=\"" << C->getTagName() << "\"";
- if (C->getNumAttrs() != 0) {
- OS << " Attrs: ";
- for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
- const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
- OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
- }
- }
- if (C->isSelfClosing())
- OS << " SelfClosing";
-}
-
-void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
- OS << " Name=\"" << C->getTagName() << "\"";
-}
-
-void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
- OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
- for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
- OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
-}
-
-void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
- OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
-
- if (C->isDirectionExplicit())
- OS << " explicitly";
- else
- OS << " implicitly";
-
- if (C->hasParamName()) {
- if (C->isParamIndexValid())
- OS << " Param=\"" << C->getParamName(FC) << "\"";
- else
- OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
- }
-
- if (C->isParamIndexValid() && !C->isVarArgParam())
- OS << " ParamIndex=" << C->getParamIndex();
-}
-
-void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
- if (C->hasParamName()) {
- if (C->isPositionValid())
- OS << " Param=\"" << C->getParamName(FC) << "\"";
- else
- OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
- }
-
- if (C->isPositionValid()) {
- OS << " Position=<";
- for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
- OS << C->getIndex(i);
- if (i != e - 1)
- OS << ", ";
- }
- OS << ">";
- }
-}
-
-void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
- OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
- " CloseName=\"" << C->getCloseName() << "\"";
-}
-
-void ASTDumper::visitVerbatimBlockLineComment(
- const VerbatimBlockLineComment *C) {
- OS << " Text=\"" << C->getText() << "\"";
-}
-
-void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
- OS << " Text=\"" << C->getText() << "\"";
-}
-
//===----------------------------------------------------------------------===//
// Type method implementations
//===----------------------------------------------------------------------===//
@@ -2816,12 +1645,16 @@ LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM) const {
const FullComment *FC = dyn_cast<FullComment>(this);
+ if (!FC)
+ return;
ASTDumper D(OS, Traits, SM);
- D.dumpFullComment(FC);
+ D.dumpComment(FC, FC);
}
LLVM_DUMP_METHOD void Comment::dumpColor() const {
const FullComment *FC = dyn_cast<FullComment>(this);
+ if (!FC)
+ return;
ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
- D.dumpFullComment(FC);
+ D.dumpComment(FC, FC);
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index b360b3910636..44832557e97b 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -13,6 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTImporter.h"
+#include "clang/AST/ASTImporterLookupTable.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTStructuralEquivalence.h"
@@ -71,10 +72,43 @@
namespace clang {
+ using llvm::make_error;
+ using llvm::Error;
+ using llvm::Expected;
+ using ExpectedType = llvm::Expected<QualType>;
+ using ExpectedStmt = llvm::Expected<Stmt *>;
+ using ExpectedExpr = llvm::Expected<Expr *>;
+ using ExpectedDecl = llvm::Expected<Decl *>;
+ using ExpectedSLoc = llvm::Expected<SourceLocation>;
+
+ std::string ImportError::toString() const {
+ // FIXME: Improve error texts.
+ switch (Error) {
+ case NameConflict:
+ return "NameConflict";
+ case UnsupportedConstruct:
+ return "UnsupportedConstruct";
+ case Unknown:
+ return "Unknown error";
+ }
+ llvm_unreachable("Invalid error code.");
+ return "Invalid error code.";
+ }
+
+ void ImportError::log(raw_ostream &OS) const {
+ OS << toString();
+ }
+
+ std::error_code ImportError::convertToErrorCode() const {
+ llvm_unreachable("Function not implemented.");
+ }
+
+ char ImportError::ID;
+
template <class T>
- SmallVector<Decl*, 2>
+ SmallVector<Decl *, 2>
getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
- SmallVector<Decl*, 2> Redecls;
+ SmallVector<Decl *, 2> Redecls;
for (auto *R : D->getFirstDecl()->redecls()) {
if (R != D->getFirstDecl())
Redecls.push_back(R);
@@ -85,9 +119,13 @@ namespace clang {
}
SmallVector<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D) {
- // Currently only FunctionDecl is supported
- auto FD = cast<FunctionDecl>(D);
- return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
+ if (auto *FD = dyn_cast<FunctionDecl>(D))
+ return getCanonicalForwardRedeclChain<FunctionDecl>(FD);
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ return getCanonicalForwardRedeclChain<VarDecl>(VD);
+ if (auto *TD = dyn_cast<TagDecl>(D))
+ return getCanonicalForwardRedeclChain<TagDecl>(TD);
+ llvm_unreachable("Bad declaration kind");
}
void updateFlags(const Decl *From, Decl *To) {
@@ -97,12 +135,110 @@ namespace clang {
To->setIsUsed();
}
- class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, QualType>,
- public DeclVisitor<ASTNodeImporter, Decl *>,
- public StmtVisitor<ASTNodeImporter, Stmt *> {
+ // FIXME: Temporary until every import returns Expected.
+ template <>
+ LLVM_NODISCARD Error
+ ASTImporter::importInto(SourceLocation &To, const SourceLocation &From) {
+ To = Import(From);
+ if (From.isValid() && To.isInvalid())
+ return llvm::make_error<ImportError>();
+ return Error::success();
+ }
+ // FIXME: Temporary until every import returns Expected.
+ template <>
+ LLVM_NODISCARD Error
+ ASTImporter::importInto(QualType &To, const QualType &From) {
+ To = Import(From);
+ if (!From.isNull() && To.isNull())
+ return llvm::make_error<ImportError>();
+ return Error::success();
+ }
+
+ class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, ExpectedType>,
+ public DeclVisitor<ASTNodeImporter, ExpectedDecl>,
+ public StmtVisitor<ASTNodeImporter, ExpectedStmt> {
ASTImporter &Importer;
- // Wrapper for an overload set.
+ // Use this instead of Importer.importInto .
+ template <typename ImportT>
+ LLVM_NODISCARD Error importInto(ImportT &To, const ImportT &From) {
+ return Importer.importInto(To, From);
+ }
+
+ // Use this to import pointers of specific type.
+ template <typename ImportT>
+ LLVM_NODISCARD Error importInto(ImportT *&To, ImportT *From) {
+ auto ToI = Importer.Import(From);
+ if (!ToI && From)
+ return make_error<ImportError>();
+ To = cast_or_null<ImportT>(ToI);
+ return Error::success();
+ // FIXME: This should be the final code.
+ //auto ToOrErr = Importer.Import(From);
+ //if (ToOrErr) {
+ // To = cast_or_null<ImportT>(*ToOrErr);
+ //}
+ //return ToOrErr.takeError();
+ }
+
+ // Call the import function of ASTImporter for a baseclass of type `T` and
+ // cast the return value to `T`.
+ template <typename T>
+ Expected<T *> import(T *From) {
+ auto *To = Importer.Import(From);
+ if (!To && From)
+ return make_error<ImportError>();
+ return cast_or_null<T>(To);
+ // FIXME: This should be the final code.
+ //auto ToOrErr = Importer.Import(From);
+ //if (!ToOrErr)
+ // return ToOrErr.takeError();
+ //return cast_or_null<T>(*ToOrErr);
+ }
+
+ template <typename T>
+ Expected<T *> import(const T *From) {
+ return import(const_cast<T *>(From));
+ }
+
+ // Call the import function of ASTImporter for type `T`.
+ template <typename T>
+ Expected<T> import(const T &From) {
+ T To = Importer.Import(From);
+ T DefaultT;
+ if (To == DefaultT && !(From == DefaultT))
+ return make_error<ImportError>();
+ return To;
+ // FIXME: This should be the final code.
+ //return Importer.Import(From);
+ }
+
+ template <class T>
+ Expected<std::tuple<T>>
+ importSeq(const T &From) {
+ Expected<T> ToOrErr = import(From);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ return std::make_tuple<T>(std::move(*ToOrErr));
+ }
+
+ // Import multiple objects with a single function call.
+ // This should work for every type for which a variant of `import` exists.
+ // The arguments are processed from left to right and import is stopped on
+ // first error.
+ template <class THead, class... TTail>
+ Expected<std::tuple<THead, TTail...>>
+ importSeq(const THead &FromHead, const TTail &...FromTail) {
+ Expected<std::tuple<THead>> ToHeadOrErr = importSeq(FromHead);
+ if (!ToHeadOrErr)
+ return ToHeadOrErr.takeError();
+ Expected<std::tuple<TTail...>> ToTailOrErr = importSeq(FromTail...);
+ if (!ToTailOrErr)
+ return ToTailOrErr.takeError();
+ return std::tuple_cat(*ToHeadOrErr, *ToTailOrErr);
+ }
+
+// Wrapper for an overload set.
template <typename ToDeclT> struct CallOverloadedCreateFun {
template <typename... Args>
auto operator()(Args &&... args)
@@ -147,16 +283,23 @@ namespace clang {
LLVM_NODISCARD bool
GetImportedOrCreateSpecialDecl(ToDeclT *&ToD, CreateFunT CreateFun,
FromDeclT *FromD, Args &&... args) {
+ // FIXME: This code is needed later.
+ //if (Importer.getImportDeclErrorIfAny(FromD)) {
+ // ToD = nullptr;
+ // return true; // Already imported but with error.
+ //}
ToD = cast_or_null<ToDeclT>(Importer.GetAlreadyImportedOrNull(FromD));
if (ToD)
return true; // Already imported.
ToD = CreateFun(std::forward<Args>(args)...);
+ // Keep track of imported Decls.
+ Importer.MapImported(FromD, ToD);
+ Importer.AddToLookupTable(ToD);
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())
@@ -170,84 +313,82 @@ namespace clang {
public:
explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
- using TypeVisitor<ASTNodeImporter, QualType>::Visit;
- using DeclVisitor<ASTNodeImporter, Decl *>::Visit;
- using StmtVisitor<ASTNodeImporter, Stmt *>::Visit;
+ using TypeVisitor<ASTNodeImporter, ExpectedType>::Visit;
+ using DeclVisitor<ASTNodeImporter, ExpectedDecl>::Visit;
+ using StmtVisitor<ASTNodeImporter, ExpectedStmt>::Visit;
// Importing types
- QualType VisitType(const Type *T);
- QualType VisitAtomicType(const AtomicType *T);
- QualType VisitBuiltinType(const BuiltinType *T);
- QualType VisitDecayedType(const DecayedType *T);
- QualType VisitComplexType(const ComplexType *T);
- QualType VisitPointerType(const PointerType *T);
- QualType VisitBlockPointerType(const BlockPointerType *T);
- QualType VisitLValueReferenceType(const LValueReferenceType *T);
- QualType VisitRValueReferenceType(const RValueReferenceType *T);
- QualType VisitMemberPointerType(const MemberPointerType *T);
- QualType VisitConstantArrayType(const ConstantArrayType *T);
- QualType VisitIncompleteArrayType(const IncompleteArrayType *T);
- QualType VisitVariableArrayType(const VariableArrayType *T);
- QualType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
+ ExpectedType VisitType(const Type *T);
+ ExpectedType VisitAtomicType(const AtomicType *T);
+ ExpectedType VisitBuiltinType(const BuiltinType *T);
+ ExpectedType VisitDecayedType(const DecayedType *T);
+ ExpectedType VisitComplexType(const ComplexType *T);
+ ExpectedType VisitPointerType(const PointerType *T);
+ ExpectedType VisitBlockPointerType(const BlockPointerType *T);
+ ExpectedType VisitLValueReferenceType(const LValueReferenceType *T);
+ ExpectedType VisitRValueReferenceType(const RValueReferenceType *T);
+ ExpectedType VisitMemberPointerType(const MemberPointerType *T);
+ ExpectedType VisitConstantArrayType(const ConstantArrayType *T);
+ ExpectedType VisitIncompleteArrayType(const IncompleteArrayType *T);
+ ExpectedType VisitVariableArrayType(const VariableArrayType *T);
+ ExpectedType VisitDependentSizedArrayType(const DependentSizedArrayType *T);
// FIXME: DependentSizedExtVectorType
- QualType VisitVectorType(const VectorType *T);
- QualType VisitExtVectorType(const ExtVectorType *T);
- QualType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
- QualType VisitFunctionProtoType(const FunctionProtoType *T);
- QualType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
- QualType VisitParenType(const ParenType *T);
- QualType VisitTypedefType(const TypedefType *T);
- QualType VisitTypeOfExprType(const TypeOfExprType *T);
+ ExpectedType VisitVectorType(const VectorType *T);
+ ExpectedType VisitExtVectorType(const ExtVectorType *T);
+ ExpectedType VisitFunctionNoProtoType(const FunctionNoProtoType *T);
+ ExpectedType VisitFunctionProtoType(const FunctionProtoType *T);
+ ExpectedType VisitUnresolvedUsingType(const UnresolvedUsingType *T);
+ ExpectedType VisitParenType(const ParenType *T);
+ ExpectedType VisitTypedefType(const TypedefType *T);
+ ExpectedType VisitTypeOfExprType(const TypeOfExprType *T);
// FIXME: DependentTypeOfExprType
- QualType VisitTypeOfType(const TypeOfType *T);
- QualType VisitDecltypeType(const DecltypeType *T);
- QualType VisitUnaryTransformType(const UnaryTransformType *T);
- QualType VisitAutoType(const AutoType *T);
- QualType VisitInjectedClassNameType(const InjectedClassNameType *T);
+ ExpectedType VisitTypeOfType(const TypeOfType *T);
+ ExpectedType VisitDecltypeType(const DecltypeType *T);
+ ExpectedType VisitUnaryTransformType(const UnaryTransformType *T);
+ ExpectedType VisitAutoType(const AutoType *T);
+ ExpectedType VisitInjectedClassNameType(const InjectedClassNameType *T);
// FIXME: DependentDecltypeType
- QualType VisitRecordType(const RecordType *T);
- QualType VisitEnumType(const EnumType *T);
- QualType VisitAttributedType(const AttributedType *T);
- QualType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
- QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
- QualType VisitTemplateSpecializationType(const TemplateSpecializationType *T);
- QualType VisitElaboratedType(const ElaboratedType *T);
- QualType VisitDependentNameType(const DependentNameType *T);
- QualType VisitPackExpansionType(const PackExpansionType *T);
- QualType VisitDependentTemplateSpecializationType(
+ ExpectedType VisitRecordType(const RecordType *T);
+ ExpectedType VisitEnumType(const EnumType *T);
+ ExpectedType VisitAttributedType(const AttributedType *T);
+ ExpectedType VisitTemplateTypeParmType(const TemplateTypeParmType *T);
+ ExpectedType VisitSubstTemplateTypeParmType(
+ const SubstTemplateTypeParmType *T);
+ ExpectedType VisitTemplateSpecializationType(
+ const TemplateSpecializationType *T);
+ ExpectedType VisitElaboratedType(const ElaboratedType *T);
+ ExpectedType VisitDependentNameType(const DependentNameType *T);
+ ExpectedType VisitPackExpansionType(const PackExpansionType *T);
+ ExpectedType VisitDependentTemplateSpecializationType(
const DependentTemplateSpecializationType *T);
- QualType VisitObjCInterfaceType(const ObjCInterfaceType *T);
- QualType VisitObjCObjectType(const ObjCObjectType *T);
- QualType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
+ ExpectedType VisitObjCInterfaceType(const ObjCInterfaceType *T);
+ ExpectedType VisitObjCObjectType(const ObjCObjectType *T);
+ ExpectedType VisitObjCObjectPointerType(const ObjCObjectPointerType *T);
// Importing declarations
- bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
- DeclContext *&LexicalDC, DeclarationName &Name,
- NamedDecl *&ToD, SourceLocation &Loc);
- void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
- 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);
+ Error ImportDeclParts(
+ NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
+ DeclarationName &Name, NamedDecl *&ToD, SourceLocation &Loc);
+ Error ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
+ Error ImportDeclarationNameLoc(
+ const DeclarationNameInfo &From, DeclarationNameInfo &To);
+ Error ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
+ Error ImportDeclContext(
+ Decl *From, DeclContext *&ToDC, DeclContext *&ToLexicalDC);
+ Error ImportImplicitMethods(const CXXRecordDecl *From, CXXRecordDecl *To);
+
+ Expected<CXXCastPath> ImportCastPath(CastExpr *E);
using Designator = DesignatedInitExpr::Designator;
- Designator ImportDesignator(const Designator &D);
-
- Optional<LambdaCapture> ImportLambdaCapture(const LambdaCapture &From);
-
/// What we should import from the definition.
enum ImportDefinitionKind {
/// 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,
-
/// Import everything.
IDK_Everything,
-
/// Import only the bare bones needed to establish a valid
/// DeclContext.
IDK_Basic
@@ -258,42 +399,44 @@ namespace clang {
(IDK == IDK_Default && !Importer.isMinimalImport());
}
- bool ImportDefinition(RecordDecl *From, RecordDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- bool ImportDefinition(VarDecl *From, VarDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- bool ImportDefinition(EnumDecl *From, EnumDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- bool ImportDefinition(ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- bool ImportDefinition(ObjCProtocolDecl *From, ObjCProtocolDecl *To,
- ImportDefinitionKind Kind = IDK_Default);
- TemplateParameterList *ImportTemplateParameterList(
+ Error ImportInitializer(VarDecl *From, VarDecl *To);
+ Error ImportDefinition(
+ RecordDecl *From, RecordDecl *To,
+ ImportDefinitionKind Kind = IDK_Default);
+ Error ImportDefinition(
+ EnumDecl *From, EnumDecl *To,
+ ImportDefinitionKind Kind = IDK_Default);
+ Error ImportDefinition(
+ ObjCInterfaceDecl *From, ObjCInterfaceDecl *To,
+ ImportDefinitionKind Kind = IDK_Default);
+ Error ImportDefinition(
+ ObjCProtocolDecl *From, ObjCProtocolDecl *To,
+ ImportDefinitionKind Kind = IDK_Default);
+ Expected<TemplateParameterList *> ImportTemplateParameterList(
TemplateParameterList *Params);
- TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
- Optional<TemplateArgumentLoc> ImportTemplateArgumentLoc(
- const TemplateArgumentLoc &TALoc);
- bool ImportTemplateArguments(const TemplateArgument *FromArgs,
- unsigned NumFromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs);
+ Error ImportTemplateArguments(
+ const TemplateArgument *FromArgs, unsigned NumFromArgs,
+ SmallVectorImpl<TemplateArgument> &ToArgs);
+ Expected<TemplateArgument>
+ ImportTemplateArgument(const TemplateArgument &From);
template <typename InContainerTy>
- bool ImportTemplateArgumentListInfo(const InContainerTy &Container,
- TemplateArgumentListInfo &ToTAInfo);
+ Error ImportTemplateArgumentListInfo(
+ const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo);
template<typename InContainerTy>
- bool ImportTemplateArgumentListInfo(SourceLocation FromLAngleLoc,
- SourceLocation FromRAngleLoc,
- const InContainerTy &Container,
- TemplateArgumentListInfo &Result);
+ Error ImportTemplateArgumentListInfo(
+ SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
+ const InContainerTy &Container, TemplateArgumentListInfo &Result);
using TemplateArgsTy = SmallVector<TemplateArgument, 8>;
- using OptionalTemplateArgsTy = Optional<TemplateArgsTy>;
- std::tuple<FunctionTemplateDecl *, OptionalTemplateArgsTy>
+ using FunctionTemplateAndArgsTy =
+ std::tuple<FunctionTemplateDecl *, TemplateArgsTy>;
+ Expected<FunctionTemplateAndArgsTy>
ImportFunctionTemplateWithTemplateArgsFromSpecialization(
FunctionDecl *FromFD);
- bool ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+ Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
@@ -307,257 +450,498 @@ namespace clang {
bool IsStructuralMatch(FunctionDecl *From, FunctionDecl *To);
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
bool IsStructuralMatch(VarTemplateDecl *From, VarTemplateDecl *To);
- Decl *VisitDecl(Decl *D);
- Decl *VisitEmptyDecl(EmptyDecl *D);
- Decl *VisitAccessSpecDecl(AccessSpecDecl *D);
- Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
- Decl *VisitTranslationUnitDecl(TranslationUnitDecl *D);
- Decl *VisitNamespaceDecl(NamespaceDecl *D);
- Decl *VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
- Decl *VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
- Decl *VisitTypedefDecl(TypedefDecl *D);
- Decl *VisitTypeAliasDecl(TypeAliasDecl *D);
- Decl *VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
- Decl *VisitLabelDecl(LabelDecl *D);
- Decl *VisitEnumDecl(EnumDecl *D);
- Decl *VisitRecordDecl(RecordDecl *D);
- Decl *VisitEnumConstantDecl(EnumConstantDecl *D);
- Decl *VisitFunctionDecl(FunctionDecl *D);
- Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
- Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
- Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
- Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
- Decl *VisitFieldDecl(FieldDecl *D);
- Decl *VisitIndirectFieldDecl(IndirectFieldDecl *D);
- Decl *VisitFriendDecl(FriendDecl *D);
- Decl *VisitObjCIvarDecl(ObjCIvarDecl *D);
- Decl *VisitVarDecl(VarDecl *D);
- Decl *VisitImplicitParamDecl(ImplicitParamDecl *D);
- Decl *VisitParmVarDecl(ParmVarDecl *D);
- Decl *VisitObjCMethodDecl(ObjCMethodDecl *D);
- Decl *VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
- Decl *VisitObjCCategoryDecl(ObjCCategoryDecl *D);
- Decl *VisitObjCProtocolDecl(ObjCProtocolDecl *D);
- Decl *VisitLinkageSpecDecl(LinkageSpecDecl *D);
- Decl *VisitUsingDecl(UsingDecl *D);
- Decl *VisitUsingShadowDecl(UsingShadowDecl *D);
- Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
- Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
-
- ObjCTypeParamList *ImportObjCTypeParamList(ObjCTypeParamList *list);
- Decl *VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
- Decl *VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
- Decl *VisitObjCImplementationDecl(ObjCImplementationDecl *D);
- Decl *VisitObjCPropertyDecl(ObjCPropertyDecl *D);
- Decl *VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
- Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
- Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
- Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
- Decl *VisitClassTemplateSpecializationDecl(
+ ExpectedDecl VisitDecl(Decl *D);
+ ExpectedDecl VisitImportDecl(ImportDecl *D);
+ ExpectedDecl VisitEmptyDecl(EmptyDecl *D);
+ ExpectedDecl VisitAccessSpecDecl(AccessSpecDecl *D);
+ ExpectedDecl VisitStaticAssertDecl(StaticAssertDecl *D);
+ ExpectedDecl VisitTranslationUnitDecl(TranslationUnitDecl *D);
+ ExpectedDecl VisitNamespaceDecl(NamespaceDecl *D);
+ ExpectedDecl VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
+ ExpectedDecl VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias);
+ ExpectedDecl VisitTypedefDecl(TypedefDecl *D);
+ ExpectedDecl VisitTypeAliasDecl(TypeAliasDecl *D);
+ ExpectedDecl VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D);
+ ExpectedDecl VisitLabelDecl(LabelDecl *D);
+ ExpectedDecl VisitEnumDecl(EnumDecl *D);
+ ExpectedDecl VisitRecordDecl(RecordDecl *D);
+ ExpectedDecl VisitEnumConstantDecl(EnumConstantDecl *D);
+ ExpectedDecl VisitFunctionDecl(FunctionDecl *D);
+ ExpectedDecl VisitCXXMethodDecl(CXXMethodDecl *D);
+ ExpectedDecl VisitCXXConstructorDecl(CXXConstructorDecl *D);
+ ExpectedDecl VisitCXXDestructorDecl(CXXDestructorDecl *D);
+ ExpectedDecl VisitCXXConversionDecl(CXXConversionDecl *D);
+ ExpectedDecl VisitFieldDecl(FieldDecl *D);
+ ExpectedDecl VisitIndirectFieldDecl(IndirectFieldDecl *D);
+ ExpectedDecl VisitFriendDecl(FriendDecl *D);
+ ExpectedDecl VisitObjCIvarDecl(ObjCIvarDecl *D);
+ ExpectedDecl VisitVarDecl(VarDecl *D);
+ ExpectedDecl VisitImplicitParamDecl(ImplicitParamDecl *D);
+ ExpectedDecl VisitParmVarDecl(ParmVarDecl *D);
+ ExpectedDecl VisitObjCMethodDecl(ObjCMethodDecl *D);
+ ExpectedDecl VisitObjCTypeParamDecl(ObjCTypeParamDecl *D);
+ ExpectedDecl VisitObjCCategoryDecl(ObjCCategoryDecl *D);
+ ExpectedDecl VisitObjCProtocolDecl(ObjCProtocolDecl *D);
+ ExpectedDecl VisitLinkageSpecDecl(LinkageSpecDecl *D);
+ ExpectedDecl VisitUsingDecl(UsingDecl *D);
+ ExpectedDecl VisitUsingShadowDecl(UsingShadowDecl *D);
+ ExpectedDecl VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
+ ExpectedDecl VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+ ExpectedDecl VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+
+ Expected<ObjCTypeParamList *>
+ ImportObjCTypeParamList(ObjCTypeParamList *list);
+
+ ExpectedDecl VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
+ ExpectedDecl VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
+ ExpectedDecl VisitObjCImplementationDecl(ObjCImplementationDecl *D);
+ ExpectedDecl VisitObjCPropertyDecl(ObjCPropertyDecl *D);
+ ExpectedDecl VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
+ ExpectedDecl VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
+ ExpectedDecl VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
+ ExpectedDecl VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
+ ExpectedDecl VisitClassTemplateDecl(ClassTemplateDecl *D);
+ ExpectedDecl VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D);
- Decl *VisitVarTemplateDecl(VarTemplateDecl *D);
- Decl *VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
- Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+ ExpectedDecl VisitVarTemplateDecl(VarTemplateDecl *D);
+ ExpectedDecl VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
+ ExpectedDecl VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
// Importing statements
- DeclGroupRef ImportDeclGroup(DeclGroupRef DG);
-
- Stmt *VisitStmt(Stmt *S);
- Stmt *VisitGCCAsmStmt(GCCAsmStmt *S);
- Stmt *VisitDeclStmt(DeclStmt *S);
- Stmt *VisitNullStmt(NullStmt *S);
- Stmt *VisitCompoundStmt(CompoundStmt *S);
- Stmt *VisitCaseStmt(CaseStmt *S);
- Stmt *VisitDefaultStmt(DefaultStmt *S);
- Stmt *VisitLabelStmt(LabelStmt *S);
- Stmt *VisitAttributedStmt(AttributedStmt *S);
- Stmt *VisitIfStmt(IfStmt *S);
- Stmt *VisitSwitchStmt(SwitchStmt *S);
- Stmt *VisitWhileStmt(WhileStmt *S);
- Stmt *VisitDoStmt(DoStmt *S);
- Stmt *VisitForStmt(ForStmt *S);
- Stmt *VisitGotoStmt(GotoStmt *S);
- Stmt *VisitIndirectGotoStmt(IndirectGotoStmt *S);
- Stmt *VisitContinueStmt(ContinueStmt *S);
- Stmt *VisitBreakStmt(BreakStmt *S);
- Stmt *VisitReturnStmt(ReturnStmt *S);
+ ExpectedStmt VisitStmt(Stmt *S);
+ ExpectedStmt VisitGCCAsmStmt(GCCAsmStmt *S);
+ ExpectedStmt VisitDeclStmt(DeclStmt *S);
+ ExpectedStmt VisitNullStmt(NullStmt *S);
+ ExpectedStmt VisitCompoundStmt(CompoundStmt *S);
+ ExpectedStmt VisitCaseStmt(CaseStmt *S);
+ ExpectedStmt VisitDefaultStmt(DefaultStmt *S);
+ ExpectedStmt VisitLabelStmt(LabelStmt *S);
+ ExpectedStmt VisitAttributedStmt(AttributedStmt *S);
+ ExpectedStmt VisitIfStmt(IfStmt *S);
+ ExpectedStmt VisitSwitchStmt(SwitchStmt *S);
+ ExpectedStmt VisitWhileStmt(WhileStmt *S);
+ ExpectedStmt VisitDoStmt(DoStmt *S);
+ ExpectedStmt VisitForStmt(ForStmt *S);
+ ExpectedStmt VisitGotoStmt(GotoStmt *S);
+ ExpectedStmt VisitIndirectGotoStmt(IndirectGotoStmt *S);
+ ExpectedStmt VisitContinueStmt(ContinueStmt *S);
+ ExpectedStmt VisitBreakStmt(BreakStmt *S);
+ ExpectedStmt VisitReturnStmt(ReturnStmt *S);
// FIXME: MSAsmStmt
// FIXME: SEHExceptStmt
// FIXME: SEHFinallyStmt
// FIXME: SEHTryStmt
// FIXME: SEHLeaveStmt
// FIXME: CapturedStmt
- Stmt *VisitCXXCatchStmt(CXXCatchStmt *S);
- Stmt *VisitCXXTryStmt(CXXTryStmt *S);
- Stmt *VisitCXXForRangeStmt(CXXForRangeStmt *S);
+ ExpectedStmt VisitCXXCatchStmt(CXXCatchStmt *S);
+ ExpectedStmt VisitCXXTryStmt(CXXTryStmt *S);
+ ExpectedStmt VisitCXXForRangeStmt(CXXForRangeStmt *S);
// FIXME: MSDependentExistsStmt
- Stmt *VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
- Stmt *VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
- Stmt *VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S);
- Stmt *VisitObjCAtTryStmt(ObjCAtTryStmt *S);
- Stmt *VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
- Stmt *VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
- Stmt *VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
+ ExpectedStmt VisitObjCForCollectionStmt(ObjCForCollectionStmt *S);
+ ExpectedStmt VisitObjCAtCatchStmt(ObjCAtCatchStmt *S);
+ ExpectedStmt VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S);
+ ExpectedStmt VisitObjCAtTryStmt(ObjCAtTryStmt *S);
+ ExpectedStmt VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+ ExpectedStmt VisitObjCAtThrowStmt(ObjCAtThrowStmt *S);
+ ExpectedStmt VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *S);
// Importing expressions
- Expr *VisitExpr(Expr *E);
- Expr *VisitVAArgExpr(VAArgExpr *E);
- Expr *VisitGNUNullExpr(GNUNullExpr *E);
- Expr *VisitPredefinedExpr(PredefinedExpr *E);
- Expr *VisitDeclRefExpr(DeclRefExpr *E);
- Expr *VisitImplicitValueInitExpr(ImplicitValueInitExpr *ILE);
- Expr *VisitDesignatedInitExpr(DesignatedInitExpr *E);
- Expr *VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
- Expr *VisitIntegerLiteral(IntegerLiteral *E);
- Expr *VisitFloatingLiteral(FloatingLiteral *E);
- Expr *VisitCharacterLiteral(CharacterLiteral *E);
- Expr *VisitStringLiteral(StringLiteral *E);
- Expr *VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
- Expr *VisitAtomicExpr(AtomicExpr *E);
- Expr *VisitAddrLabelExpr(AddrLabelExpr *E);
- Expr *VisitParenExpr(ParenExpr *E);
- Expr *VisitParenListExpr(ParenListExpr *E);
- Expr *VisitStmtExpr(StmtExpr *E);
- Expr *VisitUnaryOperator(UnaryOperator *E);
- Expr *VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
- Expr *VisitBinaryOperator(BinaryOperator *E);
- Expr *VisitConditionalOperator(ConditionalOperator *E);
- Expr *VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
- Expr *VisitOpaqueValueExpr(OpaqueValueExpr *E);
- Expr *VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
- Expr *VisitExpressionTraitExpr(ExpressionTraitExpr *E);
- Expr *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
- Expr *VisitCompoundAssignOperator(CompoundAssignOperator *E);
- Expr *VisitImplicitCastExpr(ImplicitCastExpr *E);
- Expr *VisitExplicitCastExpr(ExplicitCastExpr *E);
- Expr *VisitOffsetOfExpr(OffsetOfExpr *OE);
- Expr *VisitCXXThrowExpr(CXXThrowExpr *E);
- Expr *VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
- Expr *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
- Expr *VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
- Expr *VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
- 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);
+ ExpectedStmt VisitExpr(Expr *E);
+ ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
+ ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
+ ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
+ ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
+ ExpectedStmt VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
+ ExpectedStmt VisitDesignatedInitExpr(DesignatedInitExpr *E);
+ ExpectedStmt VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E);
+ ExpectedStmt VisitIntegerLiteral(IntegerLiteral *E);
+ ExpectedStmt VisitFloatingLiteral(FloatingLiteral *E);
+ ExpectedStmt VisitImaginaryLiteral(ImaginaryLiteral *E);
+ ExpectedStmt VisitCharacterLiteral(CharacterLiteral *E);
+ ExpectedStmt VisitStringLiteral(StringLiteral *E);
+ ExpectedStmt VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
+ ExpectedStmt VisitAtomicExpr(AtomicExpr *E);
+ ExpectedStmt VisitAddrLabelExpr(AddrLabelExpr *E);
+ ExpectedStmt VisitConstantExpr(ConstantExpr *E);
+ ExpectedStmt VisitParenExpr(ParenExpr *E);
+ ExpectedStmt VisitParenListExpr(ParenListExpr *E);
+ ExpectedStmt VisitStmtExpr(StmtExpr *E);
+ ExpectedStmt VisitUnaryOperator(UnaryOperator *E);
+ ExpectedStmt VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E);
+ ExpectedStmt VisitBinaryOperator(BinaryOperator *E);
+ ExpectedStmt VisitConditionalOperator(ConditionalOperator *E);
+ ExpectedStmt VisitBinaryConditionalOperator(BinaryConditionalOperator *E);
+ ExpectedStmt VisitOpaqueValueExpr(OpaqueValueExpr *E);
+ ExpectedStmt VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E);
+ ExpectedStmt VisitExpressionTraitExpr(ExpressionTraitExpr *E);
+ ExpectedStmt VisitArraySubscriptExpr(ArraySubscriptExpr *E);
+ ExpectedStmt VisitCompoundAssignOperator(CompoundAssignOperator *E);
+ ExpectedStmt VisitImplicitCastExpr(ImplicitCastExpr *E);
+ ExpectedStmt VisitExplicitCastExpr(ExplicitCastExpr *E);
+ ExpectedStmt VisitOffsetOfExpr(OffsetOfExpr *OE);
+ ExpectedStmt VisitCXXThrowExpr(CXXThrowExpr *E);
+ ExpectedStmt VisitCXXNoexceptExpr(CXXNoexceptExpr *E);
+ ExpectedStmt VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+ ExpectedStmt VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E);
+ ExpectedStmt VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E);
+ ExpectedStmt VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
+ ExpectedStmt VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E);
+ ExpectedStmt VisitPackExpansionExpr(PackExpansionExpr *E);
+ ExpectedStmt VisitSizeOfPackExpr(SizeOfPackExpr *E);
+ ExpectedStmt VisitCXXNewExpr(CXXNewExpr *E);
+ ExpectedStmt VisitCXXDeleteExpr(CXXDeleteExpr *E);
+ ExpectedStmt VisitCXXConstructExpr(CXXConstructExpr *E);
+ ExpectedStmt VisitCXXMemberCallExpr(CXXMemberCallExpr *E);
+ ExpectedStmt VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E);
+ ExpectedStmt VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E);
+ ExpectedStmt VisitCXXUnresolvedConstructExpr(CXXUnresolvedConstructExpr *E);
+ ExpectedStmt VisitUnresolvedLookupExpr(UnresolvedLookupExpr *E);
+ ExpectedStmt VisitUnresolvedMemberExpr(UnresolvedMemberExpr *E);
+ ExpectedStmt VisitExprWithCleanups(ExprWithCleanups *E);
+ ExpectedStmt VisitCXXThisExpr(CXXThisExpr *E);
+ ExpectedStmt VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E);
+ ExpectedStmt VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E);
+ ExpectedStmt VisitMemberExpr(MemberExpr *E);
+ ExpectedStmt VisitCallExpr(CallExpr *E);
+ ExpectedStmt VisitLambdaExpr(LambdaExpr *LE);
+ ExpectedStmt VisitInitListExpr(InitListExpr *E);
+ ExpectedStmt VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E);
+ ExpectedStmt VisitCXXInheritedCtorInitExpr(CXXInheritedCtorInitExpr *E);
+ ExpectedStmt VisitArrayInitLoopExpr(ArrayInitLoopExpr *E);
+ ExpectedStmt VisitArrayInitIndexExpr(ArrayInitIndexExpr *E);
+ ExpectedStmt VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
+ ExpectedStmt VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
+ ExpectedStmt VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
+ ExpectedStmt VisitTypeTraitExpr(TypeTraitExpr *E);
+ ExpectedStmt VisitCXXTypeidExpr(CXXTypeidExpr *E);
template<typename IIter, typename OIter>
- void ImportArray(IIter Ibegin, IIter Iend, OIter Obegin) {
+ Error ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
using ItemT = typename std::remove_reference<decltype(*Obegin)>::type;
-
- ASTImporter &ImporterRef = Importer;
- std::transform(Ibegin, Iend, Obegin,
- [&ImporterRef](ItemT From) -> ItemT {
- return ImporterRef.Import(From);
- });
- }
-
- template<typename IIter, typename OIter>
- bool ImportArrayChecked(IIter Ibegin, IIter Iend, OIter Obegin) {
- 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 * {
- auto *To = cast_or_null<ItemT>(ImporterRef.Import(From));
- if (!To && From)
- Failed = true;
- return To;
- });
- return Failed;
+ for (; Ibegin != Iend; ++Ibegin, ++Obegin) {
+ Expected<ItemT> ToOrErr = import(*Ibegin);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ *Obegin = *ToOrErr;
+ }
+ return Error::success();
}
+ // Import every item from a container structure into an output container.
+ // If error occurs, stops at first error and returns the error.
+ // The output container should have space for all needed elements (it is not
+ // expanded, new items are put into from the beginning).
template<typename InContainerTy, typename OutContainerTy>
- bool ImportContainerChecked(const InContainerTy &InContainer,
- OutContainerTy &OutContainer) {
- return ImportArrayChecked(InContainer.begin(), InContainer.end(),
- OutContainer.begin());
+ Error ImportContainerChecked(
+ const InContainerTy &InContainer, OutContainerTy &OutContainer) {
+ return ImportArrayChecked(
+ InContainer.begin(), InContainer.end(), OutContainer.begin());
}
template<typename InContainerTy, typename OIter>
- bool ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
+ Error ImportArrayChecked(const InContainerTy &InContainer, OIter Obegin) {
return ImportArrayChecked(InContainer.begin(), InContainer.end(), Obegin);
}
- // Importing overrides.
void ImportOverrides(CXXMethodDecl *ToMethod, CXXMethodDecl *FromMethod);
- FunctionDecl *FindFunctionTemplateSpecialization(FunctionDecl *FromFD);
+ Expected<FunctionDecl *> FindFunctionTemplateSpecialization(
+ FunctionDecl *FromFD);
};
+// FIXME: Temporary until every import returns Expected.
+template <>
+Expected<TemplateName> ASTNodeImporter::import(const TemplateName &From) {
+ TemplateName To = Importer.Import(From);
+ if (To.isNull() && !From.isNull())
+ return make_error<ImportError>();
+ return To;
+}
+
template <typename InContainerTy>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo(
+Error 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;
+ auto ToLAngleLocOrErr = import(FromLAngleLoc);
+ if (!ToLAngleLocOrErr)
+ return ToLAngleLocOrErr.takeError();
+ auto ToRAngleLocOrErr = import(FromRAngleLoc);
+ if (!ToRAngleLocOrErr)
+ return ToRAngleLocOrErr.takeError();
+
+ TemplateArgumentListInfo ToTAInfo(*ToLAngleLocOrErr, *ToRAngleLocOrErr);
+ if (auto Err = ImportTemplateArgumentListInfo(Container, ToTAInfo))
+ return Err;
Result = ToTAInfo;
- return false;
+ return Error::success();
}
template <>
-bool ASTNodeImporter::ImportTemplateArgumentListInfo<TemplateArgumentListInfo>(
+Error 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);
+Error ASTNodeImporter::ImportTemplateArgumentListInfo<
+ ASTTemplateArgumentListInfo>(
+ const ASTTemplateArgumentListInfo &From,
+ TemplateArgumentListInfo &Result) {
+ return ImportTemplateArgumentListInfo(
+ From.LAngleLoc, From.RAngleLoc, From.arguments(), Result);
}
-std::tuple<FunctionTemplateDecl *, ASTNodeImporter::OptionalTemplateArgsTy>
+Expected<ASTNodeImporter::FunctionTemplateAndArgsTy>
ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
FunctionDecl *FromFD) {
assert(FromFD->getTemplatedKind() ==
- FunctionDecl::TK_FunctionTemplateSpecialization);
+ FunctionDecl::TK_FunctionTemplateSpecialization);
+
+ FunctionTemplateAndArgsTy Result;
+
auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
- auto *Template = cast_or_null<FunctionTemplateDecl>(
- Importer.Import(FTSInfo->getTemplate()));
+ if (Error Err = importInto(std::get<0>(Result), FTSInfo->getTemplate()))
+ return std::move(Err);
// 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());
+ if (Error Err = ImportTemplateArguments(TemplArgs.data(), TemplArgs.size(),
+ std::get<1>(Result)))
+ return std::move(Err);
- return std::make_tuple(Template, ToTemplArgs);
+ return Result;
+}
+
+template <>
+Expected<TemplateParameterList *>
+ASTNodeImporter::import(TemplateParameterList *From) {
+ SmallVector<NamedDecl *, 4> To(From->size());
+ if (Error Err = ImportContainerChecked(*From, To))
+ return std::move(Err);
+
+ ExpectedExpr ToRequiresClause = import(From->getRequiresClause());
+ if (!ToRequiresClause)
+ return ToRequiresClause.takeError();
+
+ auto ToTemplateLocOrErr = import(From->getTemplateLoc());
+ if (!ToTemplateLocOrErr)
+ return ToTemplateLocOrErr.takeError();
+ auto ToLAngleLocOrErr = import(From->getLAngleLoc());
+ if (!ToLAngleLocOrErr)
+ return ToLAngleLocOrErr.takeError();
+ auto ToRAngleLocOrErr = import(From->getRAngleLoc());
+ if (!ToRAngleLocOrErr)
+ return ToRAngleLocOrErr.takeError();
+
+ return TemplateParameterList::Create(
+ Importer.getToContext(),
+ *ToTemplateLocOrErr,
+ *ToLAngleLocOrErr,
+ To,
+ *ToRAngleLocOrErr,
+ *ToRequiresClause);
+}
+
+template <>
+Expected<TemplateArgument>
+ASTNodeImporter::import(const TemplateArgument &From) {
+ switch (From.getKind()) {
+ case TemplateArgument::Null:
+ return TemplateArgument();
+
+ case TemplateArgument::Type: {
+ ExpectedType ToTypeOrErr = import(From.getAsType());
+ if (!ToTypeOrErr)
+ return ToTypeOrErr.takeError();
+ return TemplateArgument(*ToTypeOrErr);
+ }
+
+ case TemplateArgument::Integral: {
+ ExpectedType ToTypeOrErr = import(From.getIntegralType());
+ if (!ToTypeOrErr)
+ return ToTypeOrErr.takeError();
+ return TemplateArgument(From, *ToTypeOrErr);
+ }
+
+ case TemplateArgument::Declaration: {
+ Expected<ValueDecl *> ToOrErr = import(From.getAsDecl());
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ ExpectedType ToTypeOrErr = import(From.getParamTypeForDecl());
+ if (!ToTypeOrErr)
+ return ToTypeOrErr.takeError();
+ return TemplateArgument(*ToOrErr, *ToTypeOrErr);
+ }
+
+ case TemplateArgument::NullPtr: {
+ ExpectedType ToTypeOrErr = import(From.getNullPtrType());
+ if (!ToTypeOrErr)
+ return ToTypeOrErr.takeError();
+ return TemplateArgument(*ToTypeOrErr, /*isNullPtr*/true);
+ }
+
+ case TemplateArgument::Template: {
+ Expected<TemplateName> ToTemplateOrErr = import(From.getAsTemplate());
+ if (!ToTemplateOrErr)
+ return ToTemplateOrErr.takeError();
+
+ return TemplateArgument(*ToTemplateOrErr);
+ }
+
+ case TemplateArgument::TemplateExpansion: {
+ Expected<TemplateName> ToTemplateOrErr =
+ import(From.getAsTemplateOrTemplatePattern());
+ if (!ToTemplateOrErr)
+ return ToTemplateOrErr.takeError();
+
+ return TemplateArgument(
+ *ToTemplateOrErr, From.getNumTemplateExpansions());
+ }
+
+ case TemplateArgument::Expression:
+ if (ExpectedExpr ToExpr = import(From.getAsExpr()))
+ return TemplateArgument(*ToExpr);
+ else
+ return ToExpr.takeError();
+
+ case TemplateArgument::Pack: {
+ SmallVector<TemplateArgument, 2> ToPack;
+ ToPack.reserve(From.pack_size());
+ if (Error Err = ImportTemplateArguments(
+ From.pack_begin(), From.pack_size(), ToPack))
+ return std::move(Err);
+
+ return TemplateArgument(
+ llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
+ }
+ }
+
+ llvm_unreachable("Invalid template argument kind");
+}
+
+template <>
+Expected<TemplateArgumentLoc>
+ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) {
+ Expected<TemplateArgument> ArgOrErr = import(TALoc.getArgument());
+ if (!ArgOrErr)
+ return ArgOrErr.takeError();
+ TemplateArgument Arg = *ArgOrErr;
+
+ TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
+
+ TemplateArgumentLocInfo ToInfo;
+ if (Arg.getKind() == TemplateArgument::Expression) {
+ ExpectedExpr E = import(FromInfo.getAsExpr());
+ if (!E)
+ return E.takeError();
+ ToInfo = TemplateArgumentLocInfo(*E);
+ } else if (Arg.getKind() == TemplateArgument::Type) {
+ if (auto TSIOrErr = import(FromInfo.getAsTypeSourceInfo()))
+ ToInfo = TemplateArgumentLocInfo(*TSIOrErr);
+ else
+ return TSIOrErr.takeError();
+ } else {
+ auto ToTemplateQualifierLocOrErr =
+ import(FromInfo.getTemplateQualifierLoc());
+ if (!ToTemplateQualifierLocOrErr)
+ return ToTemplateQualifierLocOrErr.takeError();
+ auto ToTemplateNameLocOrErr = import(FromInfo.getTemplateNameLoc());
+ if (!ToTemplateNameLocOrErr)
+ return ToTemplateNameLocOrErr.takeError();
+ auto ToTemplateEllipsisLocOrErr =
+ import(FromInfo.getTemplateEllipsisLoc());
+ if (!ToTemplateEllipsisLocOrErr)
+ return ToTemplateEllipsisLocOrErr.takeError();
+
+ ToInfo = TemplateArgumentLocInfo(
+ *ToTemplateQualifierLocOrErr,
+ *ToTemplateNameLocOrErr,
+ *ToTemplateEllipsisLocOrErr);
+ }
+
+ return TemplateArgumentLoc(Arg, ToInfo);
+}
+
+template <>
+Expected<DeclGroupRef> ASTNodeImporter::import(const DeclGroupRef &DG) {
+ if (DG.isNull())
+ return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0);
+ size_t NumDecls = DG.end() - DG.begin();
+ SmallVector<Decl *, 1> ToDecls;
+ ToDecls.reserve(NumDecls);
+ for (Decl *FromD : DG) {
+ if (auto ToDOrErr = import(FromD))
+ ToDecls.push_back(*ToDOrErr);
+ else
+ return ToDOrErr.takeError();
+ }
+ return DeclGroupRef::Create(Importer.getToContext(),
+ ToDecls.begin(),
+ NumDecls);
+}
+
+template <>
+Expected<ASTNodeImporter::Designator>
+ASTNodeImporter::import(const Designator &D) {
+ if (D.isFieldDesignator()) {
+ IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName());
+
+ ExpectedSLoc ToDotLocOrErr = import(D.getDotLoc());
+ if (!ToDotLocOrErr)
+ return ToDotLocOrErr.takeError();
+
+ ExpectedSLoc ToFieldLocOrErr = import(D.getFieldLoc());
+ if (!ToFieldLocOrErr)
+ return ToFieldLocOrErr.takeError();
+
+ return Designator(ToFieldName, *ToDotLocOrErr, *ToFieldLocOrErr);
+ }
+
+ ExpectedSLoc ToLBracketLocOrErr = import(D.getLBracketLoc());
+ if (!ToLBracketLocOrErr)
+ return ToLBracketLocOrErr.takeError();
+
+ ExpectedSLoc ToRBracketLocOrErr = import(D.getRBracketLoc());
+ if (!ToRBracketLocOrErr)
+ return ToRBracketLocOrErr.takeError();
+
+ if (D.isArrayDesignator())
+ return Designator(D.getFirstExprIndex(),
+ *ToLBracketLocOrErr, *ToRBracketLocOrErr);
+
+ ExpectedSLoc ToEllipsisLocOrErr = import(D.getEllipsisLoc());
+ if (!ToEllipsisLocOrErr)
+ return ToEllipsisLocOrErr.takeError();
+
+ assert(D.isArrayRangeDesignator());
+ return Designator(
+ D.getFirstExprIndex(), *ToLBracketLocOrErr, *ToEllipsisLocOrErr,
+ *ToRBracketLocOrErr);
+}
+
+template <>
+Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
+ VarDecl *Var = nullptr;
+ if (From.capturesVariable()) {
+ if (auto VarOrErr = import(From.getCapturedVar()))
+ Var = *VarOrErr;
+ else
+ return VarOrErr.takeError();
+ }
+
+ auto LocationOrErr = import(From.getLocation());
+ if (!LocationOrErr)
+ return LocationOrErr.takeError();
+
+ SourceLocation EllipsisLoc;
+ if (From.isPackExpansion())
+ if (Error Err = importInto(EllipsisLoc, From.getEllipsisLoc()))
+ return std::move(Err);
+
+ return LambdaCapture(
+ *LocationOrErr, From.isImplicit(), From.getCaptureKind(), Var,
+ EllipsisLoc);
}
} // namespace clang
@@ -568,26 +952,30 @@ ASTNodeImporter::ImportFunctionTemplateWithTemplateArgsFromSpecialization(
using namespace clang;
-QualType ASTNodeImporter::VisitType(const Type *T) {
+ExpectedType ASTNodeImporter::VisitType(const Type *T) {
Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
<< T->getTypeClassName();
- return {};
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
}
-QualType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
- QualType UnderlyingType = Importer.Import(T->getValueType());
- if(UnderlyingType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitAtomicType(const AtomicType *T){
+ ExpectedType UnderlyingTypeOrErr = import(T->getValueType());
+ if (!UnderlyingTypeOrErr)
+ return UnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getAtomicType(UnderlyingType);
+ return Importer.getToContext().getAtomicType(*UnderlyingTypeOrErr);
}
-QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
+ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
switch (T->getKind()) {
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
case BuiltinType::Id: \
return Importer.getToContext().SingletonId;
#include "clang/Basic/OpenCLImageTypes.def"
+#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
+ case BuiltinType::Id: \
+ return Importer.getToContext().Id##Ty;
+#include "clang/Basic/OpenCLExtensionTypes.def"
#define SHARED_SINGLETON_TYPE(Expansion)
#define BUILTIN_TYPE(Id, SingletonId) \
case BuiltinType::Id: return Importer.getToContext().SingletonId;
@@ -627,183 +1015,196 @@ QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
llvm_unreachable("Invalid BuiltinType Kind!");
}
-QualType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
- QualType OrigT = Importer.Import(T->getOriginalType());
- if (OrigT.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitDecayedType(const DecayedType *T) {
+ ExpectedType ToOriginalTypeOrErr = import(T->getOriginalType());
+ if (!ToOriginalTypeOrErr)
+ return ToOriginalTypeOrErr.takeError();
- return Importer.getToContext().getDecayedType(OrigT);
+ return Importer.getToContext().getDecayedType(*ToOriginalTypeOrErr);
}
-QualType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitComplexType(const ComplexType *T) {
+ ExpectedType ToElementTypeOrErr = import(T->getElementType());
+ if (!ToElementTypeOrErr)
+ return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getComplexType(ToElementType);
+ return Importer.getToContext().getComplexType(*ToElementTypeOrErr);
}
-QualType ASTNodeImporter::VisitPointerType(const PointerType *T) {
- QualType ToPointeeType = Importer.Import(T->getPointeeType());
- if (ToPointeeType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitPointerType(const PointerType *T) {
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getPointerType(ToPointeeType);
+ return Importer.getToContext().getPointerType(*ToPointeeTypeOrErr);
}
-QualType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
+ExpectedType ASTNodeImporter::VisitBlockPointerType(const BlockPointerType *T) {
// FIXME: Check for blocks support in "to" context.
- QualType ToPointeeType = Importer.Import(T->getPointeeType());
- if (ToPointeeType.isNull())
- return {};
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getBlockPointerType(ToPointeeType);
+ return Importer.getToContext().getBlockPointerType(*ToPointeeTypeOrErr);
}
-QualType
+ExpectedType
ASTNodeImporter::VisitLValueReferenceType(const LValueReferenceType *T) {
// FIXME: Check for C++ support in "to" context.
- QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
- if (ToPointeeType.isNull())
- return {};
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getLValueReferenceType(ToPointeeType);
+ return Importer.getToContext().getLValueReferenceType(*ToPointeeTypeOrErr);
}
-QualType
+ExpectedType
ASTNodeImporter::VisitRValueReferenceType(const RValueReferenceType *T) {
// FIXME: Check for C++0x support in "to" context.
- QualType ToPointeeType = Importer.Import(T->getPointeeTypeAsWritten());
- if (ToPointeeType.isNull())
- return {};
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeTypeAsWritten());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getRValueReferenceType(ToPointeeType);
+ return Importer.getToContext().getRValueReferenceType(*ToPointeeTypeOrErr);
}
-QualType ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
+ExpectedType
+ASTNodeImporter::VisitMemberPointerType(const MemberPointerType *T) {
// FIXME: Check for C++ support in "to" context.
- QualType ToPointeeType = Importer.Import(T->getPointeeType());
- if (ToPointeeType.isNull())
- return {};
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- QualType ClassType = Importer.Import(QualType(T->getClass(), 0));
- return Importer.getToContext().getMemberPointerType(ToPointeeType,
- ClassType.getTypePtr());
+ ExpectedType ClassTypeOrErr = import(QualType(T->getClass(), 0));
+ if (!ClassTypeOrErr)
+ return ClassTypeOrErr.takeError();
+
+ return Importer.getToContext().getMemberPointerType(
+ *ToPointeeTypeOrErr, (*ClassTypeOrErr).getTypePtr());
}
-QualType ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
+ExpectedType
+ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
+ ExpectedType ToElementTypeOrErr = import(T->getElementType());
+ if (!ToElementTypeOrErr)
+ return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getConstantArrayType(ToElementType,
+ return Importer.getToContext().getConstantArrayType(*ToElementTypeOrErr,
T->getSize(),
T->getSizeModifier(),
T->getIndexTypeCVRQualifiers());
}
-QualType
+ExpectedType
ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
+ ExpectedType ToElementTypeOrErr = import(T->getElementType());
+ if (!ToElementTypeOrErr)
+ return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getIncompleteArrayType(ToElementType,
+ return Importer.getToContext().getIncompleteArrayType(*ToElementTypeOrErr,
T->getSizeModifier(),
T->getIndexTypeCVRQualifiers());
}
-QualType ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
-
- Expr *Size = Importer.Import(T->getSizeExpr());
- if (!Size)
- return {};
+ExpectedType
+ASTNodeImporter::VisitVariableArrayType(const VariableArrayType *T) {
+ QualType ToElementType;
+ Expr *ToSizeExpr;
+ SourceRange ToBracketsRange;
+ if (auto Imp = importSeq(
+ T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
+ std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
+ else
+ return Imp.takeError();
- SourceRange Brackets = Importer.Import(T->getBracketsRange());
- return Importer.getToContext().getVariableArrayType(ToElementType, Size,
- T->getSizeModifier(),
- T->getIndexTypeCVRQualifiers(),
- Brackets);
+ return Importer.getToContext().getVariableArrayType(
+ ToElementType, ToSizeExpr, T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers(), ToBracketsRange);
}
-QualType ASTNodeImporter::VisitDependentSizedArrayType(
+ExpectedType ASTNodeImporter::VisitDependentSizedArrayType(
const DependentSizedArrayType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
-
+ QualType ToElementType;
+ Expr *ToSizeExpr;
+ SourceRange ToBracketsRange;
+ if (auto Imp = importSeq(
+ T->getElementType(), T->getSizeExpr(), T->getBracketsRange()))
+ std::tie(ToElementType, ToSizeExpr, ToBracketsRange) = *Imp;
+ else
+ return Imp.takeError();
// 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);
+ ToElementType, ToSizeExpr, T->getSizeModifier(),
+ T->getIndexTypeCVRQualifiers(), ToBracketsRange);
}
-QualType ASTNodeImporter::VisitVectorType(const VectorType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitVectorType(const VectorType *T) {
+ ExpectedType ToElementTypeOrErr = import(T->getElementType());
+ if (!ToElementTypeOrErr)
+ return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getVectorType(ToElementType,
+ return Importer.getToContext().getVectorType(*ToElementTypeOrErr,
T->getNumElements(),
T->getVectorKind());
}
-QualType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
- QualType ToElementType = Importer.Import(T->getElementType());
- if (ToElementType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitExtVectorType(const ExtVectorType *T) {
+ ExpectedType ToElementTypeOrErr = import(T->getElementType());
+ if (!ToElementTypeOrErr)
+ return ToElementTypeOrErr.takeError();
- return Importer.getToContext().getExtVectorType(ToElementType,
+ return Importer.getToContext().getExtVectorType(*ToElementTypeOrErr,
T->getNumElements());
}
-QualType
+ExpectedType
ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
// FIXME: What happens if we're importing a function without a prototype
// into C++? Should we make it variadic?
- QualType ToResultType = Importer.Import(T->getReturnType());
- if (ToResultType.isNull())
- return {};
+ ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
+ if (!ToReturnTypeOrErr)
+ return ToReturnTypeOrErr.takeError();
- return Importer.getToContext().getFunctionNoProtoType(ToResultType,
+ return Importer.getToContext().getFunctionNoProtoType(*ToReturnTypeOrErr,
T->getExtInfo());
}
-QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
- QualType ToResultType = Importer.Import(T->getReturnType());
- if (ToResultType.isNull())
- return {};
+ExpectedType
+ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
+ ExpectedType ToReturnTypeOrErr = import(T->getReturnType());
+ if (!ToReturnTypeOrErr)
+ return ToReturnTypeOrErr.takeError();
// Import argument types
SmallVector<QualType, 4> ArgTypes;
for (const auto &A : T->param_types()) {
- QualType ArgType = Importer.Import(A);
- if (ArgType.isNull())
- return {};
- ArgTypes.push_back(ArgType);
+ ExpectedType TyOrErr = import(A);
+ if (!TyOrErr)
+ return TyOrErr.takeError();
+ ArgTypes.push_back(*TyOrErr);
}
// Import exception types
SmallVector<QualType, 4> ExceptionTypes;
for (const auto &E : T->exceptions()) {
- QualType ExceptionType = Importer.Import(E);
- if (ExceptionType.isNull())
- return {};
- ExceptionTypes.push_back(ExceptionType);
+ ExpectedType TyOrErr = import(E);
+ if (!TyOrErr)
+ return TyOrErr.takeError();
+ ExceptionTypes.push_back(*TyOrErr);
}
FunctionProtoType::ExtProtoInfo FromEPI = T->getExtProtoInfo();
FunctionProtoType::ExtProtoInfo ToEPI;
+ auto Imp = importSeq(
+ FromEPI.ExceptionSpec.NoexceptExpr,
+ FromEPI.ExceptionSpec.SourceDecl,
+ FromEPI.ExceptionSpec.SourceTemplate);
+ if (!Imp)
+ return Imp.takeError();
+
ToEPI.ExtInfo = FromEPI.ExtInfo;
ToEPI.Variadic = FromEPI.Variadic;
ToEPI.HasTrailingReturn = FromEPI.HasTrailingReturn;
@@ -811,112 +1212,108 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
ToEPI.RefQualifier = FromEPI.RefQualifier;
ToEPI.ExceptionSpec.Type = FromEPI.ExceptionSpec.Type;
ToEPI.ExceptionSpec.Exceptions = ExceptionTypes;
- ToEPI.ExceptionSpec.NoexceptExpr =
- Importer.Import(FromEPI.ExceptionSpec.NoexceptExpr);
- ToEPI.ExceptionSpec.SourceDecl = cast_or_null<FunctionDecl>(
- Importer.Import(FromEPI.ExceptionSpec.SourceDecl));
- ToEPI.ExceptionSpec.SourceTemplate = cast_or_null<FunctionDecl>(
- Importer.Import(FromEPI.ExceptionSpec.SourceTemplate));
+ std::tie(
+ ToEPI.ExceptionSpec.NoexceptExpr,
+ ToEPI.ExceptionSpec.SourceDecl,
+ ToEPI.ExceptionSpec.SourceTemplate) = *Imp;
- return Importer.getToContext().getFunctionType(ToResultType, ArgTypes, ToEPI);
+ return Importer.getToContext().getFunctionType(
+ *ToReturnTypeOrErr, ArgTypes, ToEPI);
}
-QualType ASTNodeImporter::VisitUnresolvedUsingType(
+ExpectedType ASTNodeImporter::VisitUnresolvedUsingType(
const UnresolvedUsingType *T) {
- const auto *ToD =
- cast_or_null<UnresolvedUsingTypenameDecl>(Importer.Import(T->getDecl()));
- if (!ToD)
- return {};
-
- auto *ToPrevD =
- cast_or_null<UnresolvedUsingTypenameDecl>(
- Importer.Import(T->getDecl()->getPreviousDecl()));
- if (!ToPrevD && T->getDecl()->getPreviousDecl())
- return {};
+ UnresolvedUsingTypenameDecl *ToD;
+ Decl *ToPrevD;
+ if (auto Imp = importSeq(T->getDecl(), T->getDecl()->getPreviousDecl()))
+ std::tie(ToD, ToPrevD) = *Imp;
+ else
+ return Imp.takeError();
- return Importer.getToContext().getTypeDeclType(ToD, ToPrevD);
+ return Importer.getToContext().getTypeDeclType(
+ ToD, cast_or_null<TypeDecl>(ToPrevD));
}
-QualType ASTNodeImporter::VisitParenType(const ParenType *T) {
- QualType ToInnerType = Importer.Import(T->getInnerType());
- if (ToInnerType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitParenType(const ParenType *T) {
+ ExpectedType ToInnerTypeOrErr = import(T->getInnerType());
+ if (!ToInnerTypeOrErr)
+ return ToInnerTypeOrErr.takeError();
- return Importer.getToContext().getParenType(ToInnerType);
+ return Importer.getToContext().getParenType(*ToInnerTypeOrErr);
}
-QualType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
- auto *ToDecl =
- dyn_cast_or_null<TypedefNameDecl>(Importer.Import(T->getDecl()));
- if (!ToDecl)
- return {};
+ExpectedType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
+ Expected<TypedefNameDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
- return Importer.getToContext().getTypeDeclType(ToDecl);
+ return Importer.getToContext().getTypeDeclType(*ToDeclOrErr);
}
-QualType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
- Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
- if (!ToExpr)
- return {};
+ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
+ ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
- return Importer.getToContext().getTypeOfExprType(ToExpr);
+ return Importer.getToContext().getTypeOfExprType(*ToExprOrErr);
}
-QualType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
- QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
- if (ToUnderlyingType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
+ ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+ if (!ToUnderlyingTypeOrErr)
+ return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getTypeOfType(ToUnderlyingType);
+ return Importer.getToContext().getTypeOfType(*ToUnderlyingTypeOrErr);
}
-QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
+ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
// FIXME: Make sure that the "to" context supports C++0x!
- Expr *ToExpr = Importer.Import(T->getUnderlyingExpr());
- if (!ToExpr)
- return {};
+ ExpectedExpr ToExprOrErr = import(T->getUnderlyingExpr());
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
- QualType UnderlyingType = Importer.Import(T->getUnderlyingType());
- if (UnderlyingType.isNull())
- return {};
+ ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+ if (!ToUnderlyingTypeOrErr)
+ return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getDecltypeType(ToExpr, UnderlyingType);
+ return Importer.getToContext().getDecltypeType(
+ *ToExprOrErr, *ToUnderlyingTypeOrErr);
}
-QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
- QualType ToBaseType = Importer.Import(T->getBaseType());
- QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType());
- if (ToBaseType.isNull() || ToUnderlyingType.isNull())
- return {};
+ExpectedType
+ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) {
+ ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
+ if (!ToBaseTypeOrErr)
+ return ToBaseTypeOrErr.takeError();
+
+ ExpectedType ToUnderlyingTypeOrErr = import(T->getUnderlyingType());
+ if (!ToUnderlyingTypeOrErr)
+ return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getUnaryTransformType(ToBaseType,
- ToUnderlyingType,
- T->getUTTKind());
+ return Importer.getToContext().getUnaryTransformType(
+ *ToBaseTypeOrErr, *ToUnderlyingTypeOrErr, T->getUTTKind());
}
-QualType ASTNodeImporter::VisitAutoType(const AutoType *T) {
+ExpectedType ASTNodeImporter::VisitAutoType(const AutoType *T) {
// FIXME: Make sure that the "to" context supports C++11!
- QualType FromDeduced = T->getDeducedType();
- QualType ToDeduced;
- if (!FromDeduced.isNull()) {
- ToDeduced = Importer.Import(FromDeduced);
- if (ToDeduced.isNull())
- return {};
- }
+ ExpectedType ToDeducedTypeOrErr = import(T->getDeducedType());
+ if (!ToDeducedTypeOrErr)
+ return ToDeducedTypeOrErr.takeError();
- return Importer.getToContext().getAutoType(ToDeduced, T->getKeyword(),
+ return Importer.getToContext().getAutoType(*ToDeducedTypeOrErr,
+ T->getKeyword(),
/*IsDependent*/false);
}
-QualType ASTNodeImporter::VisitInjectedClassNameType(
+ExpectedType ASTNodeImporter::VisitInjectedClassNameType(
const InjectedClassNameType *T) {
- auto *D = cast_or_null<CXXRecordDecl>(Importer.Import(T->getDecl()));
- if (!D)
- return {};
+ Expected<CXXRecordDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
- QualType InjType = Importer.Import(T->getInjectedSpecializationType());
- if (InjType.isNull())
- return {};
+ ExpectedType ToInjTypeOrErr = import(T->getInjectedSpecializationType());
+ if (!ToInjTypeOrErr)
+ return ToInjTypeOrErr.takeError();
// FIXME: ASTContext::getInjectedClassNameType is not suitable for AST reading
// See comments in InjectedClassNameType definition for details
@@ -927,293 +1324,287 @@ QualType ASTNodeImporter::VisitInjectedClassNameType(
};
return QualType(new (Importer.getToContext(), TypeAlignment)
- InjectedClassNameType(D, InjType), 0);
+ InjectedClassNameType(*ToDeclOrErr, *ToInjTypeOrErr), 0);
}
-QualType ASTNodeImporter::VisitRecordType(const RecordType *T) {
- auto *ToDecl = dyn_cast_or_null<RecordDecl>(Importer.Import(T->getDecl()));
- if (!ToDecl)
- return {};
+ExpectedType ASTNodeImporter::VisitRecordType(const RecordType *T) {
+ Expected<RecordDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
- return Importer.getToContext().getTagDeclType(ToDecl);
+ return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
}
-QualType ASTNodeImporter::VisitEnumType(const EnumType *T) {
- auto *ToDecl = dyn_cast_or_null<EnumDecl>(Importer.Import(T->getDecl()));
- if (!ToDecl)
- return {};
+ExpectedType ASTNodeImporter::VisitEnumType(const EnumType *T) {
+ Expected<EnumDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
- return Importer.getToContext().getTagDeclType(ToDecl);
+ return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
}
-QualType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
- QualType FromModifiedType = T->getModifiedType();
- QualType FromEquivalentType = T->getEquivalentType();
- QualType ToModifiedType;
- QualType ToEquivalentType;
-
- if (!FromModifiedType.isNull()) {
- ToModifiedType = Importer.Import(FromModifiedType);
- if (ToModifiedType.isNull())
- return {};
- }
- if (!FromEquivalentType.isNull()) {
- ToEquivalentType = Importer.Import(FromEquivalentType);
- if (ToEquivalentType.isNull())
- return {};
- }
+ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
+ ExpectedType ToModifiedTypeOrErr = import(T->getModifiedType());
+ if (!ToModifiedTypeOrErr)
+ return ToModifiedTypeOrErr.takeError();
+ ExpectedType ToEquivalentTypeOrErr = import(T->getEquivalentType());
+ if (!ToEquivalentTypeOrErr)
+ return ToEquivalentTypeOrErr.takeError();
return Importer.getToContext().getAttributedType(T->getAttrKind(),
- ToModifiedType, ToEquivalentType);
+ *ToModifiedTypeOrErr, *ToEquivalentTypeOrErr);
}
-QualType ASTNodeImporter::VisitTemplateTypeParmType(
+ExpectedType ASTNodeImporter::VisitTemplateTypeParmType(
const TemplateTypeParmType *T) {
- auto *ParmDecl =
- cast_or_null<TemplateTypeParmDecl>(Importer.Import(T->getDecl()));
- if (!ParmDecl && T->getDecl())
- return {};
+ Expected<TemplateTypeParmDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
return Importer.getToContext().getTemplateTypeParmType(
- T->getDepth(), T->getIndex(), T->isParameterPack(), ParmDecl);
+ T->getDepth(), T->getIndex(), T->isParameterPack(), *ToDeclOrErr);
}
-QualType ASTNodeImporter::VisitSubstTemplateTypeParmType(
+ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType *T) {
- const auto *Replaced =
- cast_or_null<TemplateTypeParmType>(Importer.Import(
- QualType(T->getReplacedParameter(), 0)).getTypePtr());
- if (!Replaced)
- return {};
+ ExpectedType ReplacedOrErr = import(QualType(T->getReplacedParameter(), 0));
+ if (!ReplacedOrErr)
+ return ReplacedOrErr.takeError();
+ const TemplateTypeParmType *Replaced =
+ cast<TemplateTypeParmType>((*ReplacedOrErr).getTypePtr());
- QualType Replacement = Importer.Import(T->getReplacementType());
- if (Replacement.isNull())
- return {};
- Replacement = Replacement.getCanonicalType();
+ ExpectedType ToReplacementTypeOrErr = import(T->getReplacementType());
+ if (!ToReplacementTypeOrErr)
+ return ToReplacementTypeOrErr.takeError();
return Importer.getToContext().getSubstTemplateTypeParmType(
- Replaced, Replacement);
+ Replaced, (*ToReplacementTypeOrErr).getCanonicalType());
}
-QualType ASTNodeImporter::VisitTemplateSpecializationType(
+ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
- TemplateName ToTemplate = Importer.Import(T->getTemplateName());
- if (ToTemplate.isNull())
- return {};
+ auto ToTemplateOrErr = import(T->getTemplateName());
+ if (!ToTemplateOrErr)
+ return ToTemplateOrErr.takeError();
SmallVector<TemplateArgument, 2> ToTemplateArgs;
- if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToTemplateArgs))
- return {};
+ if (Error Err = ImportTemplateArguments(
+ T->getArgs(), T->getNumArgs(), ToTemplateArgs))
+ return std::move(Err);
QualType ToCanonType;
if (!QualType(T, 0).isCanonical()) {
QualType FromCanonType
= Importer.getFromContext().getCanonicalType(QualType(T, 0));
- ToCanonType =Importer.Import(FromCanonType);
- if (ToCanonType.isNull())
- return {};
+ if (ExpectedType TyOrErr = import(FromCanonType))
+ ToCanonType = *TyOrErr;
+ else
+ return TyOrErr.takeError();
}
- return Importer.getToContext().getTemplateSpecializationType(ToTemplate,
+ return Importer.getToContext().getTemplateSpecializationType(*ToTemplateOrErr,
ToTemplateArgs,
ToCanonType);
}
-QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
- NestedNameSpecifier *ToQualifier = nullptr;
+ExpectedType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
// Note: the qualifier in an ElaboratedType is optional.
- if (T->getQualifier()) {
- ToQualifier = Importer.Import(T->getQualifier());
- if (!ToQualifier)
- return {};
- }
+ auto ToQualifierOrErr = import(T->getQualifier());
+ if (!ToQualifierOrErr)
+ return ToQualifierOrErr.takeError();
- QualType ToNamedType = Importer.Import(T->getNamedType());
- if (ToNamedType.isNull())
- return {};
+ ExpectedType ToNamedTypeOrErr = import(T->getNamedType());
+ if (!ToNamedTypeOrErr)
+ return ToNamedTypeOrErr.takeError();
- TagDecl *OwnedTagDecl =
- cast_or_null<TagDecl>(Importer.Import(T->getOwnedTagDecl()));
- if (!OwnedTagDecl && T->getOwnedTagDecl())
- return {};
+ Expected<TagDecl *> ToOwnedTagDeclOrErr = import(T->getOwnedTagDecl());
+ if (!ToOwnedTagDeclOrErr)
+ return ToOwnedTagDeclOrErr.takeError();
return Importer.getToContext().getElaboratedType(T->getKeyword(),
- ToQualifier, ToNamedType,
- OwnedTagDecl);
+ *ToQualifierOrErr,
+ *ToNamedTypeOrErr,
+ *ToOwnedTagDeclOrErr);
}
-QualType ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
- QualType Pattern = Importer.Import(T->getPattern());
- if (Pattern.isNull())
- return {};
+ExpectedType
+ASTNodeImporter::VisitPackExpansionType(const PackExpansionType *T) {
+ ExpectedType ToPatternOrErr = import(T->getPattern());
+ if (!ToPatternOrErr)
+ return ToPatternOrErr.takeError();
- return Importer.getToContext().getPackExpansionType(Pattern,
+ return Importer.getToContext().getPackExpansionType(*ToPatternOrErr,
T->getNumExpansions());
}
-QualType ASTNodeImporter::VisitDependentTemplateSpecializationType(
+ExpectedType ASTNodeImporter::VisitDependentTemplateSpecializationType(
const DependentTemplateSpecializationType *T) {
- NestedNameSpecifier *Qualifier = Importer.Import(T->getQualifier());
- if (!Qualifier && T->getQualifier())
- return {};
+ auto ToQualifierOrErr = import(T->getQualifier());
+ if (!ToQualifierOrErr)
+ return ToQualifierOrErr.takeError();
- IdentifierInfo *Name = Importer.Import(T->getIdentifier());
- if (!Name && T->getIdentifier())
- return {};
+ IdentifierInfo *ToName = Importer.Import(T->getIdentifier());
SmallVector<TemplateArgument, 2> ToPack;
ToPack.reserve(T->getNumArgs());
- if (ImportTemplateArguments(T->getArgs(), T->getNumArgs(), ToPack))
- return {};
+ if (Error Err = ImportTemplateArguments(
+ T->getArgs(), T->getNumArgs(), ToPack))
+ return std::move(Err);
return Importer.getToContext().getDependentTemplateSpecializationType(
- T->getKeyword(), Qualifier, Name, ToPack);
+ T->getKeyword(), *ToQualifierOrErr, ToName, ToPack);
}
-QualType ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
- NestedNameSpecifier *NNS = Importer.Import(T->getQualifier());
- if (!NNS && T->getQualifier())
- return QualType();
+ExpectedType
+ASTNodeImporter::VisitDependentNameType(const DependentNameType *T) {
+ auto ToQualifierOrErr = import(T->getQualifier());
+ if (!ToQualifierOrErr)
+ return ToQualifierOrErr.takeError();
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();
+ QualType Canon;
+ if (T != T->getCanonicalTypeInternal().getTypePtr()) {
+ if (ExpectedType TyOrErr = import(T->getCanonicalTypeInternal()))
+ Canon = (*TyOrErr).getCanonicalType();
+ else
+ return TyOrErr.takeError();
+ }
- return Importer.getToContext().getDependentNameType(T->getKeyword(), NNS,
+ return Importer.getToContext().getDependentNameType(T->getKeyword(),
+ *ToQualifierOrErr,
Name, Canon);
}
-QualType ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
- auto *Class =
- dyn_cast_or_null<ObjCInterfaceDecl>(Importer.Import(T->getDecl()));
- if (!Class)
- return {};
+ExpectedType
+ASTNodeImporter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
+ Expected<ObjCInterfaceDecl *> ToDeclOrErr = import(T->getDecl());
+ if (!ToDeclOrErr)
+ return ToDeclOrErr.takeError();
- return Importer.getToContext().getObjCInterfaceType(Class);
+ return Importer.getToContext().getObjCInterfaceType(*ToDeclOrErr);
}
-QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
- QualType ToBaseType = Importer.Import(T->getBaseType());
- if (ToBaseType.isNull())
- return {};
+ExpectedType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
+ ExpectedType ToBaseTypeOrErr = import(T->getBaseType());
+ if (!ToBaseTypeOrErr)
+ return ToBaseTypeOrErr.takeError();
SmallVector<QualType, 4> TypeArgs;
for (auto TypeArg : T->getTypeArgsAsWritten()) {
- QualType ImportedTypeArg = Importer.Import(TypeArg);
- if (ImportedTypeArg.isNull())
- return {};
-
- TypeArgs.push_back(ImportedTypeArg);
+ if (ExpectedType TyOrErr = import(TypeArg))
+ TypeArgs.push_back(*TyOrErr);
+ else
+ return TyOrErr.takeError();
}
SmallVector<ObjCProtocolDecl *, 4> Protocols;
for (auto *P : T->quals()) {
- auto *Protocol = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
- if (!Protocol)
- return {};
- Protocols.push_back(Protocol);
+ if (Expected<ObjCProtocolDecl *> ProtocolOrErr = import(P))
+ Protocols.push_back(*ProtocolOrErr);
+ else
+ return ProtocolOrErr.takeError();
+
}
- return Importer.getToContext().getObjCObjectType(ToBaseType, TypeArgs,
+ return Importer.getToContext().getObjCObjectType(*ToBaseTypeOrErr, TypeArgs,
Protocols,
T->isKindOfTypeAsWritten());
}
-QualType
+ExpectedType
ASTNodeImporter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- QualType ToPointeeType = Importer.Import(T->getPointeeType());
- if (ToPointeeType.isNull())
- return {};
+ ExpectedType ToPointeeTypeOrErr = import(T->getPointeeType());
+ if (!ToPointeeTypeOrErr)
+ return ToPointeeTypeOrErr.takeError();
- return Importer.getToContext().getObjCObjectPointerType(ToPointeeType);
+ return Importer.getToContext().getObjCObjectPointerType(*ToPointeeTypeOrErr);
}
//----------------------------------------------------------------------------
// Import Declarations
//----------------------------------------------------------------------------
-bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
- DeclContext *&LexicalDC,
- DeclarationName &Name,
- NamedDecl *&ToD,
- SourceLocation &Loc) {
+Error ASTNodeImporter::ImportDeclParts(
+ NamedDecl *D, DeclContext *&DC, DeclContext *&LexicalDC,
+ 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;
+ auto getLeafPointeeType = [](const Type *T) {
+ while (T->isPointerType() || T->isArrayType()) {
+ T = T->getPointeeOrArrayElementType();
+ }
+ return T;
+ };
+ for (const ParmVarDecl *P : FunDecl->parameters()) {
+ const Type *LeafT =
+ getLeafPointeeType(P->getType().getCanonicalType().getTypePtr());
+ auto *RT = dyn_cast<RecordType>(LeafT);
+ if (RT && RT->getDecl() == D) {
+ Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+ << D->getDeclKindName();
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ }
}
}
// Import the context of this declaration.
- DC = Importer.ImportContext(OrigDC);
- if (!DC)
- return true;
-
- LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return true;
- }
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return Err;
// Import the name of this declaration.
- Name = Importer.Import(D->getDeclName());
- if (D->getDeclName() && !Name)
- return true;
+ if (Error Err = importInto(Name, D->getDeclName()))
+ return Err;
// Import the location of this declaration.
- Loc = Importer.Import(D->getLocation());
+ if (Error Err = importInto(Loc, D->getLocation()))
+ return Err;
+
ToD = cast_or_null<NamedDecl>(Importer.GetAlreadyImportedOrNull(D));
- return false;
+ if (ToD)
+ if (Error Err = ASTNodeImporter(*this).ImportDefinitionIfNeeded(D, ToD))
+ return Err;
+
+ return Error::success();
}
-void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
+Error ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
if (!FromD)
- return;
+ return Error::success();
- if (!ToD) {
- ToD = Importer.Import(FromD);
- if (!ToD)
- return;
- }
-
- 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);
+ if (!ToD)
+ if (Error Err = importInto(ToD, FromD))
+ return Err;
+
+ if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
+ if (RecordDecl *ToRecord = cast<RecordDecl>(ToD)) {
+ if (FromRecord->getDefinition() && FromRecord->isCompleteDefinition() &&
+ !ToRecord->getDefinition()) {
+ if (Error Err = ImportDefinition(FromRecord, ToRecord))
+ return Err;
}
}
- return;
+ return Error::success();
}
- if (auto *FromEnum = dyn_cast<EnumDecl>(FromD)) {
- if (auto *ToEnum = cast_or_null<EnumDecl>(ToD)) {
+ if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
+ if (EnumDecl *ToEnum = cast<EnumDecl>(ToD)) {
if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
- ImportDefinition(FromEnum, ToEnum);
+ if (Error Err = ImportDefinition(FromEnum, ToEnum))
+ return Err;
}
}
- return;
+ return Error::success();
}
+
+ return Error::success();
}
-void
-ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
- DeclarationNameInfo& To) {
+Error
+ASTNodeImporter::ImportDeclarationNameLoc(
+ const DeclarationNameInfo &From, DeclarationNameInfo& To) {
// NOTE: To.Name and To.Loc are already imported.
// We only have to import To.LocInfo.
switch (To.getName().getNameKind()) {
@@ -1223,76 +1614,121 @@ ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
case DeclarationName::ObjCMultiArgSelector:
case DeclarationName::CXXUsingDirective:
case DeclarationName::CXXDeductionGuideName:
- return;
+ return Error::success();
case DeclarationName::CXXOperatorName: {
- SourceRange Range = From.getCXXOperatorNameRange();
- To.setCXXOperatorNameRange(Importer.Import(Range));
- return;
+ if (auto ToRangeOrErr = import(From.getCXXOperatorNameRange()))
+ To.setCXXOperatorNameRange(*ToRangeOrErr);
+ else
+ return ToRangeOrErr.takeError();
+ return Error::success();
}
case DeclarationName::CXXLiteralOperatorName: {
- SourceLocation Loc = From.getCXXLiteralOperatorNameLoc();
- To.setCXXLiteralOperatorNameLoc(Importer.Import(Loc));
- return;
+ if (ExpectedSLoc LocOrErr = import(From.getCXXLiteralOperatorNameLoc()))
+ To.setCXXLiteralOperatorNameLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
+ return Error::success();
}
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName: {
- TypeSourceInfo *FromTInfo = From.getNamedTypeInfo();
- To.setNamedTypeInfo(Importer.Import(FromTInfo));
- return;
+ if (auto ToTInfoOrErr = import(From.getNamedTypeInfo()))
+ To.setNamedTypeInfo(*ToTInfoOrErr);
+ else
+ return ToTInfoOrErr.takeError();
+ return Error::success();
}
}
llvm_unreachable("Unknown name kind.");
}
-void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
+Error
+ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
if (Importer.isMinimalImport() && !ForceImport) {
- Importer.ImportContext(FromDC);
- return;
+ auto ToDCOrErr = Importer.ImportContext(FromDC);
+ return ToDCOrErr.takeError();
+ }
+ llvm::SmallVector<Decl *, 8> ImportedDecls;
+ for (auto *From : FromDC->decls()) {
+ ExpectedDecl ImportedOrErr = import(From);
+ if (!ImportedOrErr)
+ // Ignore the error, continue with next Decl.
+ // FIXME: Handle this case somehow better.
+ consumeError(ImportedOrErr.takeError());
}
- for (auto *From : FromDC->decls())
- Importer.Import(From);
+ return Error::success();
+}
+
+Error ASTNodeImporter::ImportDeclContext(
+ Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
+ auto ToDCOrErr = Importer.ImportContext(FromD->getDeclContext());
+ if (!ToDCOrErr)
+ return ToDCOrErr.takeError();
+ ToDC = *ToDCOrErr;
+
+ if (FromD->getDeclContext() != FromD->getLexicalDeclContext()) {
+ auto ToLexicalDCOrErr = Importer.ImportContext(
+ FromD->getLexicalDeclContext());
+ if (!ToLexicalDCOrErr)
+ return ToLexicalDCOrErr.takeError();
+ ToLexicalDC = *ToLexicalDCOrErr;
+ } else
+ ToLexicalDC = ToDC;
+
+ return Error::success();
}
-void ASTNodeImporter::ImportImplicitMethods(
+Error 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);
+ if (FromM->isImplicit()) {
+ Expected<CXXMethodDecl *> ToMOrErr = import(FromM);
+ if (!ToMOrErr)
+ return ToMOrErr.takeError();
+ }
+
+ return Error::success();
}
-static void setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
- ASTImporter &Importer) {
+static Error 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);
+ Decl *ToTypedef = Importer.Import(FromTypedef);
+ if (!ToTypedef)
+ return make_error<ImportError>();
+ To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToTypedef));
+ // FIXME: This should be the final code.
+ //if (Expected<Decl *> ToTypedefOrErr = Importer.Import(FromTypedef))
+ // To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
+ //else
+ // return ToTypedefOrErr.takeError();
}
+ return Error::success();
}
-bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
- ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+ RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
if (To->getDefinition() || To->isBeingDefined()) {
if (Kind == IDK_Everything)
- ImportDeclContext(From, /*ForceImport=*/true);
+ return ImportDeclContext(From, /*ForceImport=*/true);
- return false;
+ return Error::success();
}
To->startDefinition();
- setTypedefNameForAnonDecl(From, To, Importer);
+ if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
+ return Err;
// Add base classes.
- if (auto *ToCXX = dyn_cast<CXXRecordDecl>(To)) {
- auto *FromCXX = cast<CXXRecordDecl>(From);
+ auto *ToCXX = dyn_cast<CXXRecordDecl>(To);
+ auto *FromCXX = dyn_cast<CXXRecordDecl>(From);
+ if (ToCXX && FromCXX && ToCXX->dataPtr() && FromCXX->dataPtr()) {
struct CXXRecordDecl::DefinitionData &ToData = ToCXX->data();
struct CXXRecordDecl::DefinitionData &FromData = FromCXX->data();
@@ -1364,228 +1800,172 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
SmallVector<CXXBaseSpecifier *, 4> Bases;
for (const auto &Base1 : FromCXX->bases()) {
- QualType T = Importer.Import(Base1.getType());
- if (T.isNull())
- return true;
+ ExpectedType TyOrErr = import(Base1.getType());
+ if (!TyOrErr)
+ return TyOrErr.takeError();
SourceLocation EllipsisLoc;
- if (Base1.isPackExpansion())
- EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
+ if (Base1.isPackExpansion()) {
+ if (ExpectedSLoc LocOrErr = import(Base1.getEllipsisLoc()))
+ EllipsisLoc = *LocOrErr;
+ else
+ return LocOrErr.takeError();
+ }
// Ensure that we have a definition for the base.
- ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
+ if (Error Err =
+ ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl()))
+ return Err;
+
+ auto RangeOrErr = import(Base1.getSourceRange());
+ if (!RangeOrErr)
+ return RangeOrErr.takeError();
+
+ auto TSIOrErr = import(Base1.getTypeSourceInfo());
+ if (!TSIOrErr)
+ return TSIOrErr.takeError();
Bases.push_back(
- new (Importer.getToContext())
- CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
- Base1.isVirtual(),
- Base1.isBaseOfClass(),
- Base1.getAccessSpecifierAsWritten(),
- Importer.Import(Base1.getTypeSourceInfo()),
- EllipsisLoc));
+ new (Importer.getToContext()) CXXBaseSpecifier(
+ *RangeOrErr,
+ Base1.isVirtual(),
+ Base1.isBaseOfClass(),
+ Base1.getAccessSpecifierAsWritten(),
+ *TSIOrErr,
+ EllipsisLoc));
}
if (!Bases.empty())
ToCXX->setBases(Bases.data(), Bases.size());
}
if (shouldForceImportDeclContext(Kind))
- ImportDeclContext(From, /*ForceImport=*/true);
+ if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+ return Err;
To->completeDefinition();
- return false;
+ return Error::success();
}
-bool ASTNodeImporter::ImportDefinition(VarDecl *From, VarDecl *To,
- ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportInitializer(VarDecl *From, VarDecl *To) {
if (To->getAnyInitializer())
- return false;
+ return Error::success();
- // FIXME: Can we really import any initializer? Alternatively, we could force
- // ourselves to import every declaration of a variable and then only use
- // getInit() here.
- To->setInit(Importer.Import(const_cast<Expr *>(From->getAnyInitializer())));
+ Expr *FromInit = From->getInit();
+ if (!FromInit)
+ return Error::success();
- // FIXME: Other bits to merge?
+ ExpectedExpr ToInitOrErr = import(FromInit);
+ if (!ToInitOrErr)
+ return ToInitOrErr.takeError();
+
+ To->setInit(*ToInitOrErr);
+ if (From->isInitKnownICE()) {
+ EvaluatedStmt *Eval = To->ensureEvaluatedStmt();
+ Eval->CheckedICE = true;
+ Eval->IsICE = From->isInitICE();
+ }
- return false;
+ // FIXME: Other bits to merge?
+ return Error::success();
}
-bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
- ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+ EnumDecl *From, EnumDecl *To, ImportDefinitionKind Kind) {
if (To->getDefinition() || To->isBeingDefined()) {
if (Kind == IDK_Everything)
- ImportDeclContext(From, /*ForceImport=*/true);
- return false;
+ return ImportDeclContext(From, /*ForceImport=*/true);
+ return Error::success();
}
To->startDefinition();
- setTypedefNameForAnonDecl(From, To, Importer);
+ if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
+ return Err;
- QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
- if (T.isNull())
- return true;
+ ExpectedType ToTypeOrErr =
+ import(Importer.getFromContext().getTypeDeclType(From));
+ if (!ToTypeOrErr)
+ return ToTypeOrErr.takeError();
- QualType ToPromotionType = Importer.Import(From->getPromotionType());
- if (ToPromotionType.isNull())
- return true;
+ ExpectedType ToPromotionTypeOrErr = import(From->getPromotionType());
+ if (!ToPromotionTypeOrErr)
+ return ToPromotionTypeOrErr.takeError();
if (shouldForceImportDeclContext(Kind))
- ImportDeclContext(From, /*ForceImport=*/true);
+ if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+ return Err;
// FIXME: we might need to merge the number of positive or negative bits
// if the enumerator lists don't match.
- To->completeDefinition(T, ToPromotionType,
+ To->completeDefinition(*ToTypeOrErr, *ToPromotionTypeOrErr,
From->getNumPositiveBits(),
From->getNumNegativeBits());
- return false;
+ return Error::success();
}
-TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
- TemplateParameterList *Params) {
+// FIXME: Remove this, use `import` instead.
+Expected<TemplateParameterList *> ASTNodeImporter::ImportTemplateParameterList(
+ TemplateParameterList *Params) {
SmallVector<NamedDecl *, 4> ToParams(Params->size());
- if (ImportContainerChecked(*Params, ToParams))
- return nullptr;
+ if (Error Err = ImportContainerChecked(*Params, ToParams))
+ return std::move(Err);
Expr *ToRequiresClause;
if (Expr *const R = Params->getRequiresClause()) {
- ToRequiresClause = Importer.Import(R);
- if (!ToRequiresClause)
- return nullptr;
+ if (Error Err = importInto(ToRequiresClause, R))
+ return std::move(Err);
} else {
ToRequiresClause = nullptr;
}
- return TemplateParameterList::Create(Importer.getToContext(),
- Importer.Import(Params->getTemplateLoc()),
- Importer.Import(Params->getLAngleLoc()),
- ToParams,
- Importer.Import(Params->getRAngleLoc()),
- ToRequiresClause);
-}
-
-TemplateArgument
-ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
- switch (From.getKind()) {
- case TemplateArgument::Null:
- return TemplateArgument();
-
- case TemplateArgument::Type: {
- QualType ToType = Importer.Import(From.getAsType());
- if (ToType.isNull())
- return {};
- return TemplateArgument(ToType);
- }
-
- case TemplateArgument::Integral: {
- QualType ToType = Importer.Import(From.getIntegralType());
- if (ToType.isNull())
- return {};
- return TemplateArgument(From, ToType);
- }
-
- case TemplateArgument::Declaration: {
- auto *To = cast_or_null<ValueDecl>(Importer.Import(From.getAsDecl()));
- QualType ToType = Importer.Import(From.getParamTypeForDecl());
- if (!To || ToType.isNull())
- return {};
- return TemplateArgument(To, ToType);
- }
-
- case TemplateArgument::NullPtr: {
- QualType ToType = Importer.Import(From.getNullPtrType());
- if (ToType.isNull())
- return {};
- return TemplateArgument(ToType, /*isNullPtr*/true);
- }
-
- case TemplateArgument::Template: {
- TemplateName ToTemplate = Importer.Import(From.getAsTemplate());
- if (ToTemplate.isNull())
- return {};
-
- return TemplateArgument(ToTemplate);
- }
-
- case TemplateArgument::TemplateExpansion: {
- TemplateName ToTemplate
- = Importer.Import(From.getAsTemplateOrTemplatePattern());
- if (ToTemplate.isNull())
- return {};
-
- return TemplateArgument(ToTemplate, From.getNumTemplateExpansions());
- }
-
- case TemplateArgument::Expression:
- if (Expr *ToExpr = Importer.Import(From.getAsExpr()))
- return TemplateArgument(ToExpr);
- return TemplateArgument();
-
- case TemplateArgument::Pack: {
- SmallVector<TemplateArgument, 2> ToPack;
- ToPack.reserve(From.pack_size());
- if (ImportTemplateArguments(From.pack_begin(), From.pack_size(), ToPack))
- return {};
-
- return TemplateArgument(
- llvm::makeArrayRef(ToPack).copy(Importer.getToContext()));
- }
- }
-
- llvm_unreachable("Invalid template argument kind");
-}
-
-Optional<TemplateArgumentLoc>
-ASTNodeImporter::ImportTemplateArgumentLoc(const TemplateArgumentLoc &TALoc) {
- TemplateArgument Arg = ImportTemplateArgument(TALoc.getArgument());
- TemplateArgumentLocInfo FromInfo = TALoc.getLocInfo();
- TemplateArgumentLocInfo ToInfo;
- if (Arg.getKind() == TemplateArgument::Expression) {
- Expr *E = Importer.Import(FromInfo.getAsExpr());
- ToInfo = TemplateArgumentLocInfo(E);
- if (!E)
- return None;
- } else if (Arg.getKind() == TemplateArgument::Type) {
- if (TypeSourceInfo *TSI = Importer.Import(FromInfo.getAsTypeSourceInfo()))
- ToInfo = TemplateArgumentLocInfo(TSI);
+ auto ToTemplateLocOrErr = import(Params->getTemplateLoc());
+ if (!ToTemplateLocOrErr)
+ return ToTemplateLocOrErr.takeError();
+ auto ToLAngleLocOrErr = import(Params->getLAngleLoc());
+ if (!ToLAngleLocOrErr)
+ return ToLAngleLocOrErr.takeError();
+ auto ToRAngleLocOrErr = import(Params->getRAngleLoc());
+ if (!ToRAngleLocOrErr)
+ return ToRAngleLocOrErr.takeError();
+
+ return TemplateParameterList::Create(
+ Importer.getToContext(),
+ *ToTemplateLocOrErr,
+ *ToLAngleLocOrErr,
+ ToParams,
+ *ToRAngleLocOrErr,
+ ToRequiresClause);
+}
+
+Error ASTNodeImporter::ImportTemplateArguments(
+ const TemplateArgument *FromArgs, unsigned NumFromArgs,
+ SmallVectorImpl<TemplateArgument> &ToArgs) {
+ for (unsigned I = 0; I != NumFromArgs; ++I) {
+ if (auto ToOrErr = import(FromArgs[I]))
+ ToArgs.push_back(*ToOrErr);
else
- return None;
- } else {
- ToInfo = TemplateArgumentLocInfo(
- Importer.Import(FromInfo.getTemplateQualifierLoc()),
- Importer.Import(FromInfo.getTemplateNameLoc()),
- Importer.Import(FromInfo.getTemplateEllipsisLoc()));
+ return ToOrErr.takeError();
}
- return TemplateArgumentLoc(Arg, ToInfo);
-}
-
-bool ASTNodeImporter::ImportTemplateArguments(const TemplateArgument *FromArgs,
- unsigned NumFromArgs,
- SmallVectorImpl<TemplateArgument> &ToArgs) {
- for (unsigned I = 0; I != NumFromArgs; ++I) {
- TemplateArgument To = ImportTemplateArgument(FromArgs[I]);
- if (To.isNull() && !FromArgs[I].isNull())
- return true;
- ToArgs.push_back(To);
- }
+ return Error::success();
+}
- return false;
+// FIXME: Do not forget to remove this and use only 'import'.
+Expected<TemplateArgument>
+ASTNodeImporter::ImportTemplateArgument(const TemplateArgument &From) {
+ return import(From);
}
-// 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(
+Error ASTNodeImporter::ImportTemplateArgumentListInfo(
const InContainerTy &Container, TemplateArgumentListInfo &ToTAInfo) {
for (const auto &FromLoc : Container) {
- if (auto ToLoc = ImportTemplateArgumentLoc(FromLoc))
- ToTAInfo.addArgument(*ToLoc);
+ if (auto ToLocOrErr = import(FromLoc))
+ ToTAInfo.addArgument(*ToLocOrErr);
else
- return true;
+ return ToLocOrErr.takeError();
}
- return false;
+ return Error::success();
}
static StructuralEquivalenceKind
@@ -1682,30 +2062,31 @@ bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
return Ctx.IsEquivalent(From, To);
}
-Decl *ASTNodeImporter::VisitDecl(Decl *D) {
+ExpectedDecl ASTNodeImporter::VisitDecl(Decl *D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return nullptr;
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
}
-Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
- // Import the context of this declaration.
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- if (!DC)
- return nullptr;
+ExpectedDecl ASTNodeImporter::VisitImportDecl(ImportDecl *D) {
+ Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
+ << D->getDeclKindName();
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
+}
- DeclContext *LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
- }
+ExpectedDecl ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
+ // Import the context of this declaration.
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
// Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
+ ExpectedSLoc LocOrErr = import(D->getLocation());
+ if (!LocOrErr)
+ return LocOrErr.takeError();
EmptyDecl *ToD;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, Loc))
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, *LocOrErr))
return ToD;
ToD->setLexicalDeclContext(LexicalDC);
@@ -1713,7 +2094,7 @@ Decl *ASTNodeImporter::VisitEmptyDecl(EmptyDecl *D) {
return ToD;
}
-Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
TranslationUnitDecl *ToD =
Importer.getToContext().getTranslationUnitDecl();
@@ -1722,18 +2103,23 @@ Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
return ToD;
}
-Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
- SourceLocation Loc = Importer.Import(D->getLocation());
- SourceLocation ColonLoc = Importer.Import(D->getColonLoc());
+ExpectedDecl ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
+ ExpectedSLoc LocOrErr = import(D->getLocation());
+ if (!LocOrErr)
+ return LocOrErr.takeError();
+ auto ColonLocOrErr = import(D->getColonLoc());
+ if (!ColonLocOrErr)
+ return ColonLocOrErr.takeError();
// Import the context of this declaration.
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- if (!DC)
- return nullptr;
+ auto DCOrErr = Importer.ImportContext(D->getDeclContext());
+ if (!DCOrErr)
+ return DCOrErr.takeError();
+ DeclContext *DC = *DCOrErr;
AccessSpecDecl *ToD;
if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), D->getAccess(),
- DC, Loc, ColonLoc))
+ DC, *LocOrErr, *ColonLocOrErr))
return ToD;
// Lexical DeclContext and Semantic DeclContext
@@ -1744,29 +2130,26 @@ Decl *ASTNodeImporter::VisitAccessSpecDecl(AccessSpecDecl *D) {
return ToD;
}
-Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- if (!DC)
- return nullptr;
-
+ExpectedDecl ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
+ auto DCOrErr = Importer.ImportContext(D->getDeclContext());
+ if (!DCOrErr)
+ return DCOrErr.takeError();
+ DeclContext *DC = *DCOrErr;
DeclContext *LexicalDC = DC;
- // Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
-
- Expr *AssertExpr = Importer.Import(D->getAssertExpr());
- if (!AssertExpr)
- return nullptr;
-
- StringLiteral *FromMsg = D->getMessage();
- auto *ToMsg = cast_or_null<StringLiteral>(Importer.Import(FromMsg));
- if (!ToMsg && FromMsg)
- return nullptr;
+ SourceLocation ToLocation, ToRParenLoc;
+ Expr *ToAssertExpr;
+ StringLiteral *ToMessage;
+ if (auto Imp = importSeq(
+ D->getLocation(), D->getAssertExpr(), D->getMessage(), D->getRParenLoc()))
+ std::tie(ToLocation, ToAssertExpr, ToMessage, ToRParenLoc) = *Imp;
+ else
+ return Imp.takeError();
StaticAssertDecl *ToD;
if (GetImportedOrCreateDecl(
- ToD, D, Importer.getToContext(), DC, Loc, AssertExpr, ToMsg,
- Importer.Import(D->getRParenLoc()), D->isFailed()))
+ ToD, D, Importer.getToContext(), DC, ToLocation, ToAssertExpr, ToMessage,
+ ToRParenLoc, D->isFailed()))
return ToD;
ToD->setLexicalDeclContext(LexicalDC);
@@ -1774,14 +2157,14 @@ Decl *ASTNodeImporter::VisitStaticAssertDecl(StaticAssertDecl *D) {
return ToD;
}
-Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
// Import the major distinguishing characteristics of this namespace.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -1796,8 +2179,7 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
MergeWithNamespace = cast<NamespaceDecl>(DC)->getAnonymousNamespace();
} else {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Namespace))
continue;
@@ -1815,15 +2197,21 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
Name = Importer.HandleNameConflict(Name, DC, Decl::IDNS_Namespace,
ConflictingDecls.data(),
ConflictingDecls.size());
+ if (!Name)
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+
// Create the "to" namespace, if needed.
NamespaceDecl *ToNamespace = MergeWithNamespace;
if (!ToNamespace) {
if (GetImportedOrCreateDecl(
ToNamespace, D, Importer.getToContext(), DC, D->isInline(),
- Importer.Import(D->getLocStart()), Loc, Name.getAsIdentifierInfo(),
+ *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
/*PrevDecl=*/nullptr))
return ToNamespace;
ToNamespace->setLexicalDeclContext(LexicalDC);
@@ -1840,43 +2228,42 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
}
Importer.MapImported(D, ToNamespace);
- ImportDeclContext(D);
+ if (Error Err = ImportDeclContext(D))
+ return std::move(Err);
return ToNamespace;
}
-Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
// Import the major distinguishing characteristics of this namespace.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *LookupD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, LookupD, Loc))
+ return std::move(Err);
if (LookupD)
return LookupD;
// NOTE: No conflict resolution is done for namespace aliases now.
- auto *TargetDecl = cast_or_null<NamespaceDecl>(
- Importer.Import(D->getNamespace()));
- if (!TargetDecl)
- return nullptr;
-
- IdentifierInfo *ToII = Importer.Import(D->getIdentifier());
- if (!ToII)
- return nullptr;
-
- NestedNameSpecifierLoc ToQLoc = Importer.Import(D->getQualifierLoc());
- if (D->getQualifierLoc() && !ToQLoc)
- return nullptr;
+ SourceLocation ToNamespaceLoc, ToAliasLoc, ToTargetNameLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ NamespaceDecl *ToNamespace;
+ if (auto Imp = importSeq(
+ D->getNamespaceLoc(), D->getAliasLoc(), D->getQualifierLoc(),
+ D->getTargetNameLoc(), D->getNamespace()))
+ std::tie(
+ ToNamespaceLoc, ToAliasLoc, ToQualifierLoc, ToTargetNameLoc,
+ ToNamespace) = *Imp;
+ else
+ return Imp.takeError();
+ IdentifierInfo *ToIdentifier = Importer.Import(D->getIdentifier());
NamespaceAliasDecl *ToD;
- if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC,
- Importer.Import(D->getNamespaceLoc()),
- Importer.Import(D->getAliasLoc()), ToII, ToQLoc,
- Importer.Import(D->getTargetNameLoc()),
- TargetDecl))
+ if (GetImportedOrCreateDecl(
+ ToD, D, Importer.getToContext(), DC, ToNamespaceLoc, ToAliasLoc,
+ ToIdentifier, ToQualifierLoc, ToTargetNameLoc, ToNamespace))
return ToD;
ToD->setLexicalDeclContext(LexicalDC);
@@ -1885,14 +2272,15 @@ Decl *ASTNodeImporter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
return ToD;
}
-Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
+ExpectedDecl
+ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
// Import the major distinguishing characteristics of this typedef.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -1902,15 +2290,21 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
if (auto *FoundTypedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
- if (Importer.IsStructurallyEquivalent(D->getUnderlyingType(),
- FoundTypedef->getUnderlyingType()))
- return Importer.MapImported(D, FoundTypedef);
+ QualType FromUT = D->getUnderlyingType();
+ QualType FoundUT = FoundTypedef->getUnderlyingType();
+ if (Importer.IsStructurallyEquivalent(FromUT, FoundUT)) {
+ // If the "From" context has a complete underlying type but we
+ // already have a complete underlying type then return with that.
+ if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType())
+ return Importer.MapImported(D, FoundTypedef);
+ }
+ // FIXME Handle redecl chain.
+ break;
}
ConflictingDecls.push_back(FoundDecl);
@@ -1921,28 +2315,30 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- // Import the underlying type of this typedef;
- QualType T = Importer.Import(D->getUnderlyingType());
- if (T.isNull())
- return nullptr;
+ QualType ToUnderlyingType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ SourceLocation ToBeginLoc;
+ if (auto Imp = importSeq(
+ D->getUnderlyingType(), D->getTypeSourceInfo(), D->getBeginLoc()))
+ std::tie(ToUnderlyingType, ToTypeSourceInfo, ToBeginLoc) = *Imp;
+ else
+ return Imp.takeError();
// Create the new typedef node.
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- SourceLocation StartL = Importer.Import(D->getLocStart());
-
+ // FIXME: ToUnderlyingType is not used.
TypedefNameDecl *ToTypedef;
if (IsAlias) {
if (GetImportedOrCreateDecl<TypeAliasDecl>(
- ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
- Name.getAsIdentifierInfo(), TInfo))
+ ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
+ Name.getAsIdentifierInfo(), ToTypeSourceInfo))
return ToTypedef;
} else if (GetImportedOrCreateDecl<TypedefDecl>(
- ToTypedef, D, Importer.getToContext(), DC, StartL, Loc,
- Name.getAsIdentifierInfo(), TInfo))
+ ToTypedef, D, Importer.getToContext(), DC, ToBeginLoc, Loc,
+ Name.getAsIdentifierInfo(), ToTypeSourceInfo))
return ToTypedef;
ToTypedef->setAccess(D->getAccess());
@@ -1956,22 +2352,23 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
return ToTypedef;
}
-Decl *ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTypedefDecl(TypedefDecl *D) {
return VisitTypedefNameDecl(D, /*IsAlias=*/false);
}
-Decl *ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitTypeAliasDecl(TypeAliasDecl *D) {
return VisitTypedefNameDecl(D, /*IsAlias=*/true);
}
-Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
// Import the major distinguishing characteristics of this typedef.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *FoundD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, FoundD, Loc))
+ return std::move(Err);
if (FoundD)
return FoundD;
@@ -1981,8 +2378,7 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
@@ -1996,26 +2392,23 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- TemplateParameterList *Params = ImportTemplateParameterList(
- D->getTemplateParameters());
- if (!Params)
- return nullptr;
-
- auto *TemplDecl = cast_or_null<TypeAliasDecl>(
- Importer.Import(D->getTemplatedDecl()));
- if (!TemplDecl)
- return nullptr;
+ TemplateParameterList *ToTemplateParameters;
+ TypeAliasDecl *ToTemplatedDecl;
+ if (auto Imp = importSeq(D->getTemplateParameters(), D->getTemplatedDecl()))
+ std::tie(ToTemplateParameters, ToTemplatedDecl) = *Imp;
+ else
+ return Imp.takeError();
TypeAliasTemplateDecl *ToAlias;
if (GetImportedOrCreateDecl(ToAlias, D, Importer.getToContext(), DC, Loc,
- Name, Params, TemplDecl))
+ Name, ToTemplateParameters, ToTemplatedDecl))
return ToAlias;
- TemplDecl->setDescribedAliasTemplate(ToAlias);
+ ToTemplatedDecl->setDescribedAliasTemplate(ToAlias);
ToAlias->setAccess(D->getAccess());
ToAlias->setLexicalDeclContext(LexicalDC);
@@ -2023,48 +2416,53 @@ Decl *ASTNodeImporter::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
return ToAlias;
}
-Decl *ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitLabelDecl(LabelDecl *D) {
// Import the major distinguishing characteristics of this label.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
assert(LexicalDC->isFunctionOrMethod());
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;
+ if (D->isGnuLocal()) {
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+ if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
+ Name.getAsIdentifierInfo(), *BeginLocOrErr))
+ return ToLabel;
+
+ } else {
+ if (GetImportedOrCreateDecl(ToLabel, D, Importer.getToContext(), DC, Loc,
+ Name.getAsIdentifierInfo()))
+ return ToLabel;
+
+ }
- ToLabel->setStmt(Label);
+ Expected<LabelStmt *> ToStmtOrErr = import(D->getStmt());
+ if (!ToStmtOrErr)
+ return ToStmtOrErr.takeError();
+
+ ToLabel->setStmt(*ToStmtOrErr);
ToLabel->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToLabel);
return ToLabel;
}
-Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// Import the major distinguishing characteristics of this enum.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -2072,7 +2470,9 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
if (!SearchName && D->getTypedefNameForAnonDecl()) {
- SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
+ if (Error Err = importInto(
+ SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
+ return std::move(Err);
IDNS = Decl::IDNS_Ordinary;
} else if (Importer.getToContext().getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Ordinary;
@@ -2080,19 +2480,18 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// We may already have an enum of the same name; try to find and match it.
if (!DC->isFunctionOrMethod() && SearchName) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
+ auto FoundDecls =
+ Importer.findDeclsInToCtx(DC, SearchName);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- Decl *Found = FoundDecl;
- if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
+ if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- Found = Tag->getDecl();
+ FoundDecl = Tag->getDecl();
}
- if (auto *FoundEnum = dyn_cast<EnumDecl>(Found)) {
+ if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
if (IsStructuralMatch(D, FoundEnum))
return Importer.MapImported(D, FoundEnum);
}
@@ -2104,53 +2503,69 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
Name = Importer.HandleNameConflict(Name, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
+ if (!Name)
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
+ SourceLocation ToBeginLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ QualType ToIntegerType;
+ if (auto Imp = importSeq(
+ D->getBeginLoc(), D->getQualifierLoc(), D->getIntegerType()))
+ std::tie(ToBeginLoc, ToQualifierLoc, ToIntegerType) = *Imp;
+ else
+ return Imp.takeError();
+
// Create the enum declaration.
EnumDecl *D2;
if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), DC, Importer.Import(D->getLocStart()),
+ D2, D, Importer.getToContext(), DC, ToBeginLoc,
Loc, Name.getAsIdentifierInfo(), nullptr, D->isScoped(),
D->isScopedUsingClassTag(), D->isFixed()))
return D2;
- // Import the qualifier, if any.
- D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ D2->setQualifierInfo(ToQualifierLoc);
+ D2->setIntegerType(ToIntegerType);
D2->setAccess(D->getAccess());
D2->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(D2);
- // Import the integer type.
- QualType ToIntegerType = Importer.Import(D->getIntegerType());
- if (ToIntegerType.isNull())
- return nullptr;
- D2->setIntegerType(ToIntegerType);
-
// Import the definition
- if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return nullptr;
+ if (D->isCompleteDefinition())
+ if (Error Err = ImportDefinition(D, D2))
+ return std::move(Err);
return D2;
}
-Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
+ bool IsFriendTemplate = false;
+ if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
+ IsFriendTemplate =
+ DCXX->getDescribedClassTemplate() &&
+ DCXX->getDescribedClassTemplate()->getFriendObjectKind() !=
+ Decl::FOK_None;
+ }
+
// If this record has a definition in the translation unit we're coming from,
// but this particular declaration is not that definition, import the
// definition and map to that.
TagDecl *Definition = D->getDefinition();
if (Definition && Definition != D &&
+ // Friend template declaration must be imported on its own.
+ !IsFriendTemplate &&
// In contrast to a normal CXXRecordDecl, the implicit
// CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
// The definition of the implicit CXXRecordDecl in this case is the
// ClassTemplateSpecializationDecl itself. Thus, we start with an extra
// condition in order to be able to import the implict Decl.
!D->isImplicit()) {
- Decl *ImportedDef = Importer.Import(Definition);
- if (!ImportedDef)
- return nullptr;
+ ExpectedDecl ImportedDefOrErr = import(Definition);
+ if (!ImportedDefOrErr)
+ return ImportedDefOrErr.takeError();
- return Importer.MapImported(D, ImportedDef);
+ return Importer.MapImported(D, *ImportedDefOrErr);
}
// Import the major distinguishing characteristics of this record.
@@ -2158,8 +2573,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -2167,19 +2582,19 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
if (!SearchName && D->getTypedefNameForAnonDecl()) {
- SearchName = Importer.Import(D->getTypedefNameForAnonDecl()->getDeclName());
+ if (Error Err = importInto(
+ SearchName, D->getTypedefNameForAnonDecl()->getDeclName()))
+ return std::move(Err);
IDNS = Decl::IDNS_Ordinary;
} else if (Importer.getToContext().getLangOpts().CPlusPlus)
- IDNS |= Decl::IDNS_Ordinary;
+ IDNS |= Decl::IDNS_Ordinary | Decl::IDNS_TagFriend;
// We may already have a record of the same name; try to find and match it.
- RecordDecl *AdoptDecl = nullptr;
RecordDecl *PrevDecl = nullptr;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
-
+ auto FoundDecls =
+ Importer.findDeclsInToCtx(DC, SearchName);
if (!FoundDecls.empty()) {
// We're going to have to compare D against potentially conflicting Decls, so complete it.
if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
@@ -2196,30 +2611,23 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Found = Tag->getDecl();
}
- if (D->getDescribedTemplate()) {
- if (auto *Template = dyn_cast<ClassTemplateDecl>(Found))
- Found = Template->getTemplatedDecl();
- else
- continue;
- }
-
if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
- if (!SearchName) {
+ // Do not emit false positive diagnostic in case of unnamed
+ // struct/union and in case of anonymous structs. Would be false
+ // because there may be several anonymous/unnamed structs in a class.
+ // E.g. these are both valid:
+ // struct A { // unnamed structs
+ // struct { struct A *next; } entry0;
+ // struct { struct A *next; } entry1;
+ // };
+ // struct X { struct { int a; }; struct { int b; }; }; // anon structs
+ if (!SearchName)
if (!IsStructuralMatch(D, FoundRecord, false))
continue;
- }
- PrevDecl = FoundRecord;
-
- if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
- if ((SearchName && !D->isCompleteDefinition())
- || (D->isCompleteDefinition() &&
- D->isAnonymousStructOrUnion()
- == FoundDef->isAnonymousStructOrUnion() &&
- IsStructuralMatch(D, FoundDef))) {
- // The record types structurally match, or the "from" translation
- // unit only had a forward declaration anyway; call it the same
- // function.
+ if (IsStructuralMatch(D, FoundRecord)) {
+ RecordDecl *FoundDef = FoundRecord->getDefinition();
+ if (D->isThisDeclarationADefinition() && FoundDef) {
// FIXME: Structural equivalence check should check for same
// user-defined methods.
Importer.MapImported(D, FoundDef);
@@ -2227,178 +2635,178 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
auto *FoundCXX = dyn_cast<CXXRecordDecl>(FoundDef);
assert(FoundCXX && "Record type mismatch");
- if (D->isCompleteDefinition() && !Importer.isMinimalImport())
+ if (!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);
+ if (Error Err = ImportImplicitMethods(DCXX, FoundCXX))
+ return std::move(Err);
}
- return FoundDef;
}
- } else if (!D->isCompleteDefinition()) {
- // We have a forward declaration of this type, so adopt that forward
- // declaration rather than building a new one.
-
- // If one or both can be completed from external storage then try one
- // last time to complete and compare them before doing this.
-
- if (FoundRecord->hasExternalLexicalStorage() &&
- !FoundRecord->isCompleteDefinition())
- FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
- if (D->hasExternalLexicalStorage())
- D->getASTContext().getExternalSource()->CompleteType(D);
-
- if (FoundRecord->isCompleteDefinition() &&
- D->isCompleteDefinition() &&
- !IsStructuralMatch(D, FoundRecord))
- continue;
-
- AdoptDecl = FoundRecord;
- continue;
- } else if (!SearchName) {
- continue;
+ PrevDecl = FoundRecord->getMostRecentDecl();
+ break;
}
}
ConflictingDecls.push_back(FoundDecl);
- }
+ } // for
if (!ConflictingDecls.empty() && SearchName) {
Name = Importer.HandleNameConflict(Name, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
+ if (!Name)
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+
// Create the record declaration.
- RecordDecl *D2 = AdoptDecl;
- SourceLocation StartLoc = Importer.Import(D->getLocStart());
- if (!D2) {
- CXXRecordDecl *D2CXX = nullptr;
- if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
- if (DCXX->isLambda()) {
- TypeSourceInfo *TInfo = Importer.Import(DCXX->getLambdaTypeInfo());
- 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;
- 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 {
- if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
- D->getTagKind(), DC, StartLoc, Loc,
- Name.getAsIdentifierInfo(),
- cast_or_null<CXXRecordDecl>(PrevDecl)))
- return D2CXX;
- }
+ RecordDecl *D2 = nullptr;
+ CXXRecordDecl *D2CXX = nullptr;
+ if (auto *DCXX = dyn_cast<CXXRecordDecl>(D)) {
+ if (DCXX->isLambda()) {
+ auto TInfoOrErr = import(DCXX->getLambdaTypeInfo());
+ if (!TInfoOrErr)
+ return TInfoOrErr.takeError();
+ if (GetImportedOrCreateSpecialDecl(
+ D2CXX, CXXRecordDecl::CreateLambda, D, Importer.getToContext(),
+ DC, *TInfoOrErr, Loc, DCXX->isDependentLambda(),
+ DCXX->isGenericLambda(), DCXX->getLambdaCaptureDefault()))
+ return D2CXX;
+ ExpectedDecl CDeclOrErr = import(DCXX->getLambdaContextDecl());
+ if (!CDeclOrErr)
+ return CDeclOrErr.takeError();
+ D2CXX->setLambdaMangling(DCXX->getLambdaManglingNumber(), *CDeclOrErr);
+ } else if (DCXX->isInjectedClassName()) {
+ // We have to be careful to do a similar dance to the one in
+ // Sema::ActOnStartCXXMemberDeclarations
+ const bool DelayTypeCreation = true;
+ if (GetImportedOrCreateDecl(
+ D2CXX, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
+ cast_or_null<CXXRecordDecl>(PrevDecl), DelayTypeCreation))
+ return D2CXX;
+ Importer.getToContext().getTypeDeclType(
+ D2CXX, dyn_cast<CXXRecordDecl>(DC));
+ } else {
+ if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
+ D->getTagKind(), DC, *BeginLocOrErr, Loc,
+ Name.getAsIdentifierInfo(),
+ cast_or_null<CXXRecordDecl>(PrevDecl)))
+ return D2CXX;
+ }
- D2 = D2CXX;
- D2->setAccess(D->getAccess());
- D2->setLexicalDeclContext(LexicalDC);
- if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
- LexicalDC->addDeclInternal(D2);
-
- if (ClassTemplateDecl *FromDescribed =
- DCXX->getDescribedClassTemplate()) {
- 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);
+ D2 = D2CXX;
+ D2->setAccess(D->getAccess());
+ D2->setLexicalDeclContext(LexicalDC);
+ if (!DCXX->getDescribedClassTemplate() || DCXX->isImplicit())
+ LexicalDC->addDeclInternal(D2);
+
+ if (LexicalDC != DC && D->isInIdentifierNamespace(Decl::IDNS_TagFriend))
+ DC->makeDeclVisibleInContext(D2);
+
+ if (ClassTemplateDecl *FromDescribed =
+ DCXX->getDescribedClassTemplate()) {
+ ClassTemplateDecl *ToDescribed;
+ if (Error Err = importInto(ToDescribed, FromDescribed))
+ return std::move(Err);
+ D2CXX->setDescribedClassTemplate(ToDescribed);
+ if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
+ // 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;
}
}
- } else if (MemberSpecializationInfo *MemberInfo =
+ // Create an injected type for the whole redecl chain.
+ SmallVector<Decl *, 2> Redecls =
+ getCanonicalForwardRedeclChain(D2CXX);
+ for (auto *R : Redecls) {
+ auto *RI = cast<CXXRecordDecl>(R);
+ RI->setTypeForDecl(nullptr);
+ // Below we create a new injected type and assign that to the
+ // canonical decl, subsequent declarations in the chain will reuse
+ // that type.
+ Importer.getToContext().getInjectedClassNameType(
+ RI, ToDescribed->getInjectedClassNameSpecialization());
+ }
+ // Set the new type for the previous injected decl too.
+ if (Injected) {
+ Injected->setTypeForDecl(nullptr);
+ Importer.getToContext().getTypeDeclType(Injected, D2CXX);
+ }
+ }
+ } else if (MemberSpecializationInfo *MemberInfo =
DCXX->getMemberSpecializationInfo()) {
TemplateSpecializationKind SK =
MemberInfo->getTemplateSpecializationKind();
CXXRecordDecl *FromInst = DCXX->getInstantiatedFromMemberClass();
- auto *ToInst =
- cast_or_null<CXXRecordDecl>(Importer.Import(FromInst));
- if (FromInst && !ToInst)
- return nullptr;
- D2CXX->setInstantiationOfMemberClass(ToInst, SK);
- D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
- Importer.Import(MemberInfo->getPointOfInstantiation()));
- }
- } else {
- if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
- D->getTagKind(), DC, StartLoc, Loc,
- Name.getAsIdentifierInfo(), PrevDecl))
- return D2;
- D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
+
+ if (Expected<CXXRecordDecl *> ToInstOrErr = import(FromInst))
+ D2CXX->setInstantiationOfMemberClass(*ToInstOrErr, SK);
+ else
+ return ToInstOrErr.takeError();
+
+ if (ExpectedSLoc POIOrErr =
+ import(MemberInfo->getPointOfInstantiation()))
+ D2CXX->getMemberSpecializationInfo()->setPointOfInstantiation(
+ *POIOrErr);
+ else
+ return POIOrErr.takeError();
}
- D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
- if (D->isAnonymousStructOrUnion())
- D2->setAnonymousStructOrUnion(true);
+ } else {
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(),
+ D->getTagKind(), DC, *BeginLocOrErr, Loc,
+ Name.getAsIdentifierInfo(), PrevDecl))
+ return D2;
+ D2->setLexicalDeclContext(LexicalDC);
+ LexicalDC->addDeclInternal(D2);
}
- Importer.MapImported(D, D2);
+ if (auto QualifierLocOrErr = import(D->getQualifierLoc()))
+ D2->setQualifierInfo(*QualifierLocOrErr);
+ else
+ return QualifierLocOrErr.takeError();
- if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
- return nullptr;
+ if (D->isAnonymousStructOrUnion())
+ D2->setAnonymousStructOrUnion(true);
+
+ if (D->isCompleteDefinition())
+ if (Error Err = ImportDefinition(D, D2, IDK_Default))
+ return std::move(Err);
return D2;
}
-Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
// Import the major distinguishing characteristics of this enumerator.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
-
// Determine whether there are any other declarations with the same name and
// in the same context.
if (!LexicalDC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
@@ -2416,18 +2824,22 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- Expr *Init = Importer.Import(D->getInitExpr());
- if (D->getInitExpr() && !Init)
- return nullptr;
+ ExpectedType TypeOrErr = import(D->getType());
+ if (!TypeOrErr)
+ return TypeOrErr.takeError();
+
+ ExpectedExpr InitOrErr = import(D->getInitExpr());
+ if (!InitOrErr)
+ return InitOrErr.takeError();
EnumConstantDecl *ToEnumerator;
if (GetImportedOrCreateDecl(
ToEnumerator, D, Importer.getToContext(), cast<EnumDecl>(DC), Loc,
- Name.getAsIdentifierInfo(), T, Init, D->getInitVal()))
+ Name.getAsIdentifierInfo(), *TypeOrErr, *InitOrErr, D->getInitVal()))
return ToEnumerator;
ToEnumerator->setAccess(D->getAccess());
@@ -2436,52 +2848,57 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
return ToEnumerator;
}
-bool ASTNodeImporter::ImportTemplateInformation(FunctionDecl *FromFD,
- FunctionDecl *ToFD) {
+Error ASTNodeImporter::ImportTemplateInformation(
+ FunctionDecl *FromFD, FunctionDecl *ToFD) {
switch (FromFD->getTemplatedKind()) {
case FunctionDecl::TK_NonTemplate:
case FunctionDecl::TK_FunctionTemplate:
- return false;
+ return Error::success();
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;
+
+ if (Expected<FunctionDecl *> InstFDOrErr =
+ import(FromFD->getInstantiatedFromMemberFunction()))
+ ToFD->setInstantiationOfMemberFunction(*InstFDOrErr, TSK);
+ else
+ return InstFDOrErr.takeError();
+
+ if (ExpectedSLoc POIOrErr = import(
+ FromFD->getMemberSpecializationInfo()->getPointOfInstantiation()))
+ ToFD->getMemberSpecializationInfo()->setPointOfInstantiation(*POIOrErr);
+ else
+ return POIOrErr.takeError();
+
+ return Error::success();
}
case FunctionDecl::TK_FunctionTemplateSpecialization: {
- FunctionTemplateDecl* Template;
- OptionalTemplateArgsTy ToTemplArgs;
- std::tie(Template, ToTemplArgs) =
+ auto FunctionAndArgsOrErr =
ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
- if (!Template || !ToTemplArgs)
- return true;
+ if (!FunctionAndArgsOrErr)
+ return FunctionAndArgsOrErr.takeError();
TemplateArgumentList *ToTAList = TemplateArgumentList::CreateCopy(
- Importer.getToContext(), *ToTemplArgs);
+ Importer.getToContext(), std::get<1>(*FunctionAndArgsOrErr));
auto *FTSInfo = FromFD->getTemplateSpecializationInfo();
TemplateArgumentListInfo ToTAInfo;
const auto *FromTAArgsAsWritten = FTSInfo->TemplateArgumentsAsWritten;
if (FromTAArgsAsWritten)
- if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ToTAInfo))
- return true;
+ if (Error Err = ImportTemplateArgumentListInfo(
+ *FromTAArgsAsWritten, ToTAInfo))
+ return Err;
- SourceLocation POI = Importer.Import(FTSInfo->getPointOfInstantiation());
+ ExpectedSLoc POIOrErr = import(FTSInfo->getPointOfInstantiation());
+ if (!POIOrErr)
+ return POIOrErr.takeError();
TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
ToFD->setFunctionTemplateSpecialization(
- Template, ToTAList, /* InsertPos= */ nullptr,
- TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, POI);
- return false;
+ std::get<0>(*FunctionAndArgsOrErr), ToTAList, /* InsertPos= */ nullptr,
+ TSK, FromTAArgsAsWritten ? &ToTAInfo : nullptr, *POIOrErr);
+ return Error::success();
}
case FunctionDecl::TK_DependentFunctionTemplateSpecialization: {
@@ -2489,53 +2906,56 @@ bool ASTNodeImporter::ImportTemplateInformation(FunctionDecl *FromFD,
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);
+ if (Expected<FunctionTemplateDecl *> ToFTDOrErr =
+ import(FromInfo->getTemplate(I)))
+ TemplDecls.addDecl(*ToFTDOrErr);
else
- return true;
+ return ToFTDOrErr.takeError();
}
// Import TemplateArgumentListInfo.
TemplateArgumentListInfo ToTAInfo;
- if (ImportTemplateArgumentListInfo(
- FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
- llvm::makeArrayRef(FromInfo->getTemplateArgs(),
- FromInfo->getNumTemplateArgs()),
- ToTAInfo))
- return true;
+ if (Error Err = ImportTemplateArgumentListInfo(
+ FromInfo->getLAngleLoc(), FromInfo->getRAngleLoc(),
+ llvm::makeArrayRef(
+ FromInfo->getTemplateArgs(), FromInfo->getNumTemplateArgs()),
+ ToTAInfo))
+ return Err;
ToFD->setDependentTemplateSpecialization(Importer.getToContext(),
TemplDecls, ToTAInfo);
- return false;
+ return Error::success();
}
}
llvm_unreachable("All cases should be covered!");
}
-FunctionDecl *
+Expected<FunctionDecl *>
ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
- FunctionTemplateDecl* Template;
- OptionalTemplateArgsTy ToTemplArgs;
- std::tie(Template, ToTemplArgs) =
+ auto FunctionAndArgsOrErr =
ImportFunctionTemplateWithTemplateArgsFromSpecialization(FromFD);
- if (!Template || !ToTemplArgs)
- return nullptr;
+ if (!FunctionAndArgsOrErr)
+ return FunctionAndArgsOrErr.takeError();
+ FunctionTemplateDecl *Template;
+ TemplateArgsTy ToTemplArgs;
+ std::tie(Template, ToTemplArgs) = *FunctionAndArgsOrErr;
void *InsertPos = nullptr;
- auto *FoundSpec = Template->findSpecialization(*ToTemplArgs, InsertPos);
+ auto *FoundSpec = Template->findSpecialization(ToTemplArgs, InsertPos);
return FoundSpec;
}
-Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
- SmallVector<Decl*, 2> Redecls = getCanonicalForwardRedeclChain(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;
+ for (; RedeclIt != Redecls.end() && *RedeclIt != D; ++RedeclIt) {
+ ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
+ if (!ToRedeclOrErr)
+ return ToRedeclOrErr.takeError();
+ }
assert(*RedeclIt == D);
// Import the major distinguishing characteristics of this function.
@@ -2543,8 +2963,8 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -2552,16 +2972,18 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
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.
+ // existing specialization in the "to" context. The lookup 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);
+ auto FoundFunctionOrErr = FindFunctionTemplateSpecialization(D);
+ if (!FoundFunctionOrErr)
+ return FoundFunctionOrErr.takeError();
+ if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
+ if (D->doesThisDeclarationHaveABody() && FoundFunction->hasBody())
+ return Importer.MapImported(D, FoundFunction);
FoundByLookup = FoundFunction;
}
}
@@ -2570,20 +2992,11 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
else if (!LexicalDC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- // 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()) {
@@ -2622,13 +3035,14 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
DeclarationNameInfo NameInfo(Name, Loc);
// Import additional name location/type info.
- ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+ if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+ return std::move(Err);
QualType FromTy = D->getType();
bool usedDifferentExceptionSpec = false;
@@ -2649,84 +3063,93 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
}
- // Import the type.
- QualType T = Importer.Import(FromTy);
- if (T.isNull())
- return nullptr;
+ QualType T;
+ TypeSourceInfo *TInfo;
+ SourceLocation ToInnerLocStart, ToEndLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ FromTy, D->getTypeSourceInfo(), D->getInnerLocStart(),
+ D->getQualifierLoc(), D->getEndLoc()))
+ std::tie(T, TInfo, ToInnerLocStart, ToQualifierLoc, ToEndLoc) = *Imp;
+ else
+ return Imp.takeError();
// Import the function parameters.
SmallVector<ParmVarDecl *, 8> Parameters;
for (auto P : D->parameters()) {
- auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
- if (!ToP)
- return nullptr;
-
- Parameters.push_back(ToP);
+ if (Expected<ParmVarDecl *> ToPOrErr = import(P))
+ Parameters.push_back(*ToPOrErr);
+ else
+ return ToPOrErr.takeError();
}
- 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 (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()))
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ ToInnerLocStart, NameInfo, T, TInfo,
+ FromConstructor->isExplicit(),
+ D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
return ToFunction;
- if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
- SmallVector<CXXCtorInitializer *, 4> CtorInitializers;
- for (auto *I : FromConstructor->inits()) {
- auto *ToI = cast_or_null<CXXCtorInitializer>(Importer.Import(I));
- if (!ToI && I)
- return nullptr;
- CtorInitializers.push_back(ToI);
- }
- auto **Memory =
- new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
- std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
- auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
- ToCtor->setCtorInitializers(Memory);
- ToCtor->setNumCtorInitializers(NumInitializers);
- }
} else if (isa<CXXDestructorDecl>(D)) {
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- InnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
- D->isImplicit()))
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ ToInnerLocStart, 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(),
+ ToInnerLocStart, 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(),
+ ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
Method->isInlineSpecified(), D->isConstexpr(), SourceLocation()))
return ToFunction;
} else {
if (GetImportedOrCreateDecl(ToFunction, D, Importer.getToContext(), DC,
- InnerLocStart, NameInfo, T, TInfo,
+ ToInnerLocStart, NameInfo, T, TInfo,
D->getStorageClass(), D->isInlineSpecified(),
D->hasWrittenPrototype(), D->isConstexpr()))
return ToFunction;
}
- // Import the qualifier, if any.
- ToFunction->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ // Connect the redecl chain.
+ if (FoundByLookup) {
+ auto *Recent = const_cast<FunctionDecl *>(
+ FoundByLookup->getMostRecentDecl());
+ ToFunction->setPreviousDecl(Recent);
+ }
+
+ // Import Ctor initializers.
+ if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+ if (unsigned NumInitializers = FromConstructor->getNumCtorInitializers()) {
+ SmallVector<CXXCtorInitializer *, 4> CtorInitializers(NumInitializers);
+ // Import first, then allocate memory and copy if there was no error.
+ if (Error Err = ImportContainerChecked(
+ FromConstructor->inits(), CtorInitializers))
+ return std::move(Err);
+ auto **Memory =
+ new (Importer.getToContext()) CXXCtorInitializer *[NumInitializers];
+ std::copy(CtorInitializers.begin(), CtorInitializers.end(), Memory);
+ auto *ToCtor = cast<CXXConstructorDecl>(ToFunction);
+ ToCtor->setCtorInitializers(Memory);
+ ToCtor->setNumCtorInitializers(NumInitializers);
+ }
+ }
+
+ ToFunction->setQualifierInfo(ToQualifierLoc);
ToFunction->setAccess(D->getAccess());
ToFunction->setLexicalDeclContext(LexicalDC);
ToFunction->setVirtualAsWritten(D->isVirtualAsWritten());
ToFunction->setTrivial(D->isTrivial());
ToFunction->setPure(D->isPure());
- ToFunction->setRangeEnd(Importer.Import(D->getLocEnd()));
+ ToFunction->setRangeEnd(ToEndLoc);
// Set the parameters.
for (auto *Param : Parameters) {
@@ -2735,12 +3158,6 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
ToFunction->setParams(Parameters);
- if (FoundByLookup) {
- auto *Recent = const_cast<FunctionDecl *>(
- FoundByLookup->getMostRecentDecl());
- ToFunction->setPreviousDecl(Recent);
- }
-
// We need to complete creation of FunctionProtoTypeLoc manually with setting
// params it refers to.
if (TInfo) {
@@ -2753,30 +3170,33 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (usedDifferentExceptionSpec) {
// Update FunctionProtoType::ExtProtoInfo.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
- ToFunction->setType(T);
+ if (ExpectedType TyOrErr = import(D->getType()))
+ ToFunction->setType(*TyOrErr);
+ else
+ return TyOrErr.takeError();
}
// Import the describing template function, if any.
- if (FromFT)
- if (!Importer.Import(FromFT))
- return nullptr;
+ if (FromFT) {
+ auto ToFTOrErr = import(FromFT);
+ if (!ToFTOrErr)
+ return ToFTOrErr.takeError();
+ }
if (D->doesThisDeclarationHaveABody()) {
if (Stmt *FromBody = D->getBody()) {
- if (Stmt *ToBody = Importer.Import(FromBody)) {
- ToFunction->setBody(ToBody);
- }
+ if (ExpectedStmt ToBodyOrErr = import(FromBody))
+ ToFunction->setBody(*ToBodyOrErr);
+ else
+ return ToBodyOrErr.takeError();
}
}
// FIXME: Other bits to merge?
// If it is a template, import all related things.
- if (ImportTemplateInformation(D, ToFunction))
- return nullptr;
+ if (Error Err = ImportTemplateInformation(D, ToFunction))
+ return std::move(Err);
bool IsFriend = D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend);
@@ -2796,133 +3216,139 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
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);
+ // Import the rest of the chain. I.e. import all subsequent declarations.
+ for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
+ ExpectedDecl ToRedeclOrErr = import(*RedeclIt);
+ if (!ToRedeclOrErr)
+ return ToRedeclOrErr.takeError();
+ }
+
return ToFunction;
}
-Decl *ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXMethodDecl(CXXMethodDecl *D) {
return VisitFunctionDecl(D);
}
-Decl *ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
return VisitCXXMethodDecl(D);
}
-Decl *ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
return VisitCXXMethodDecl(D);
}
-Decl *ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitCXXConversionDecl(CXXConversionDecl *D) {
return VisitCXXMethodDecl(D);
}
-static unsigned getFieldIndex(Decl *F) {
- auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
- if (!Owner)
- return 0;
-
- unsigned Index = 1;
- for (const auto *D : Owner->noload_decls()) {
- if (D == F)
- return Index;
-
- if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
- ++Index;
- }
-
- return Index;
-}
-
-Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
// Import the major distinguishing characteristics of a variable.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Determine whether we've already imported this field.
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
- if (auto *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
+ if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
// For anonymous fields, match up by index.
- if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
+ if (!Name &&
+ ASTImporter::getFieldIndex(D) !=
+ ASTImporter::getFieldIndex(FoundField))
continue;
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundField->getType())) {
Importer.MapImported(D, FoundField);
+ // In case of a FieldDecl of a ClassTemplateSpecializationDecl, the
+ // initializer of a FieldDecl might not had been instantiated in the
+ // "To" context. However, the "From" context might instantiated that,
+ // thus we have to merge that.
+ if (Expr *FromInitializer = D->getInClassInitializer()) {
+ // We don't have yet the initializer set.
+ if (FoundField->hasInClassInitializer() &&
+ !FoundField->getInClassInitializer()) {
+ if (ExpectedExpr ToInitializerOrErr = import(FromInitializer))
+ FoundField->setInClassInitializer(*ToInitializerOrErr);
+ else {
+ // We can't return error here,
+ // since we already mapped D as imported.
+ // FIXME: warning message?
+ consumeError(ToInitializerOrErr.takeError());
+ return FoundField;
+ }
+ }
+ }
return FoundField;
}
+ // FIXME: Why is this case not handled with calling HandleNameConflict?
Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- // Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
-
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- Expr *BitWidth = Importer.Import(D->getBitWidth());
- if (!BitWidth && D->getBitWidth())
- return nullptr;
+ QualType ToType;
+ TypeSourceInfo *ToTInfo;
+ Expr *ToBitWidth;
+ SourceLocation ToInnerLocStart;
+ Expr *ToInitializer;
+ if (auto Imp = importSeq(
+ D->getType(), D->getTypeSourceInfo(), D->getBitWidth(),
+ D->getInnerLocStart(), D->getInClassInitializer()))
+ std::tie(
+ ToType, ToTInfo, ToBitWidth, ToInnerLocStart, ToInitializer) = *Imp;
+ else
+ return Imp.takeError();
FieldDecl *ToField;
if (GetImportedOrCreateDecl(ToField, D, Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()), Loc,
- Name.getAsIdentifierInfo(), T, TInfo, BitWidth,
- D->isMutable(), D->getInClassInitStyle()))
+ ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
+ ToType, ToTInfo, ToBitWidth, D->isMutable(),
+ D->getInClassInitStyle()))
return ToField;
ToField->setAccess(D->getAccess());
ToField->setLexicalDeclContext(LexicalDC);
- if (Expr *FromInitializer = D->getInClassInitializer()) {
- Expr *ToInitializer = Importer.Import(FromInitializer);
- if (ToInitializer)
- ToField->setInClassInitializer(ToInitializer);
- else
- return nullptr;
- }
+ if (ToInitializer)
+ ToField->setInClassInitializer(ToInitializer);
ToField->setImplicit(D->isImplicit());
LexicalDC->addDeclInternal(ToField);
return ToField;
}
-Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
// Import the major distinguishing characteristics of a variable.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Determine whether we've already imported this field.
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (auto *FoundField = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
// For anonymous indirect fields, match up by index.
- if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
+ if (!Name &&
+ ASTImporter::getFieldIndex(D) !=
+ ASTImporter::getFieldIndex(FoundField))
continue;
if (Importer.IsStructurallyEquivalent(D->getType(),
@@ -2936,39 +3362,40 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
if (!Name && I < N-1)
continue;
+ // FIXME: Why is this case not handled with calling HandleNameConflict?
Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
// Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ auto TypeOrErr = import(D->getType());
+ if (!TypeOrErr)
+ return TypeOrErr.takeError();
auto **NamedChain =
new (Importer.getToContext()) NamedDecl*[D->getChainingSize()];
unsigned i = 0;
- for (auto *PI : D->chain()) {
- Decl *D = Importer.Import(PI);
- if (!D)
- return nullptr;
- NamedChain[i++] = cast<NamedDecl>(D);
- }
+ for (auto *PI : D->chain())
+ if (Expected<NamedDecl *> ToD = import(PI))
+ NamedChain[i++] = *ToD;
+ else
+ return ToD.takeError();
llvm::MutableArrayRef<NamedDecl *> CH = {NamedChain, D->getChainingSize()};
IndirectFieldDecl *ToIndirectField;
if (GetImportedOrCreateDecl(ToIndirectField, D, Importer.getToContext(), DC,
- Loc, Name.getAsIdentifierInfo(), T, CH))
+ Loc, Name.getAsIdentifierInfo(), *TypeOrErr, CH))
// FIXME here we leak `NamedChain` which is allocated before
return ToIndirectField;
- for (const auto *A : D->attrs())
- ToIndirectField->addAttr(Importer.Import(A));
+ for (const auto *Attr : D->attrs())
+ ToIndirectField->addAttr(Importer.Import(Attr));
ToIndirectField->setAccess(D->getAccess());
ToIndirectField->setLexicalDeclContext(LexicalDC);
@@ -2976,16 +3403,14 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
return ToIndirectField;
}
-Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
// Import the major distinguishing characteristics of a declaration.
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- DeclContext *LexicalDC = D->getDeclContext() == D->getLexicalDeclContext()
- ? DC : Importer.ImportContext(D->getLexicalDeclContext());
- if (!DC || !LexicalDC)
- return nullptr;
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
// Determine whether we've already imported this decl.
- // FriendDecl is not a NamedDecl so we cannot use localUncachedLookup.
+ // FriendDecl is not a NamedDecl so we cannot use lookup.
auto *RD = cast<CXXRecordDecl>(DC);
FriendDecl *ImportedFriend = RD->getFirstFriend();
@@ -3007,30 +3432,42 @@ Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
// Not found. Create it.
FriendDecl::FriendUnion ToFU;
if (NamedDecl *FriendD = D->getFriendDecl()) {
- auto *ToFriendD = cast_or_null<NamedDecl>(Importer.Import(FriendD));
- if (ToFriendD && FriendD->getFriendObjectKind() != Decl::FOK_None &&
+ NamedDecl *ToFriendD;
+ if (Error Err = importInto(ToFriendD, FriendD))
+ return std::move(Err);
+
+ if (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;
+ } else { // The friend is a type, not a decl.
+ if (auto TSIOrErr = import(D->getFriendType()))
+ ToFU = *TSIOrErr;
+ else
+ return TSIOrErr.takeError();
+ }
SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0; I < D->NumTPLists; I++) {
- TemplateParameterList *List = ImportTemplateParameterList(FromTPLists[I]);
- if (!List)
- return nullptr;
- ToTPLists[I] = List;
+ if (auto ListOrErr = ImportTemplateParameterList(FromTPLists[I]))
+ ToTPLists[I] = *ListOrErr;
+ else
+ return ListOrErr.takeError();
}
+ auto LocationOrErr = import(D->getLocation());
+ if (!LocationOrErr)
+ return LocationOrErr.takeError();
+ auto FriendLocOrErr = import(D->getFriendLoc());
+ if (!FriendLocOrErr)
+ return FriendLocOrErr.takeError();
+
FriendDecl *FrD;
if (GetImportedOrCreateDecl(FrD, D, Importer.getToContext(), DC,
- Importer.Import(D->getLocation()), ToFU,
- Importer.Import(D->getFriendLoc()), ToTPLists))
+ *LocationOrErr, ToFU,
+ *FriendLocOrErr, ToTPLists))
return FrD;
FrD->setAccess(D->getAccess());
@@ -3039,22 +3476,21 @@ Decl *ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
return FrD;
}
-Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
// Import the major distinguishing characteristics of an ivar.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Determine whether we've already imported this ivar
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
- if (auto *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
+ if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundIvar->getType())) {
Importer.MapImported(D, FoundIvar);
@@ -3065,26 +3501,27 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
<< Name << D->getType() << FoundIvar->getType();
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- // Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
-
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- Expr *BitWidth = Importer.Import(D->getBitWidth());
- if (!BitWidth && D->getBitWidth())
- return nullptr;
+ QualType ToType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ Expr *ToBitWidth;
+ SourceLocation ToInnerLocStart;
+ if (auto Imp = importSeq(
+ D->getType(), D->getTypeSourceInfo(), D->getBitWidth(), D->getInnerLocStart()))
+ std::tie(ToType, ToTypeSourceInfo, ToBitWidth, ToInnerLocStart) = *Imp;
+ else
+ return Imp.takeError();
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()))
+ ToInnerLocStart, Loc, Name.getAsIdentifierInfo(),
+ ToType, ToTypeSourceInfo,
+ D->getAccessControl(),ToBitWidth, D->getSynthesize()))
return ToIvar;
ToIvar->setLexicalDeclContext(LexicalDC);
@@ -3092,25 +3529,36 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
return ToIvar;
}
-Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *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) {
+ ExpectedDecl RedeclOrErr = import(*RedeclIt);
+ if (!RedeclOrErr)
+ return RedeclOrErr.takeError();
+ }
+ assert(*RedeclIt == D);
+
// Import the major distinguishing characteristics of a variable.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Try to find a variable in our own ("to") context with the same name and
// in the same context as the variable we're importing.
+ VarDecl *FoundByLookup = nullptr;
if (D->isFileVarDecl()) {
- VarDecl *MergeWithVar = nullptr;
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
@@ -3121,7 +3569,23 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
D->hasExternalFormalLinkage()) {
if (Importer.IsStructurallyEquivalent(D->getType(),
FoundVar->getType())) {
- MergeWithVar = FoundVar;
+
+ // The VarDecl in the "From" context has a definition, but in the
+ // "To" context we already have a definition.
+ VarDecl *FoundDef = FoundVar->getDefinition();
+ if (D->isThisDeclarationADefinition() && FoundDef)
+ // FIXME Check for ODR error if the two definitions have
+ // different initializers?
+ return Importer.MapImported(D, FoundDef);
+
+ // The VarDecl in the "From" context has an initializer, but in the
+ // "To" context we already have an initializer.
+ const VarDecl *FoundDInit = nullptr;
+ if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
+ // FIXME Diagnose ODR error if the two initializers are different?
+ return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
+
+ FoundByLookup = FoundVar;
break;
}
@@ -3133,16 +3597,16 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
if (isa<IncompleteArrayType>(FoundArray) &&
isa<ConstantArrayType>(TArray)) {
// Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ if (auto TyOrErr = import(D->getType()))
+ FoundVar->setType(*TyOrErr);
+ else
+ return TyOrErr.takeError();
- FoundVar->setType(T);
- MergeWithVar = FoundVar;
+ FoundByLookup = FoundVar;
break;
} else if (isa<IncompleteArrayType>(TArray) &&
isa<ConstantArrayType>(FoundArray)) {
- MergeWithVar = FoundVar;
+ FoundByLookup = FoundVar;
break;
}
}
@@ -3157,125 +3621,110 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
ConflictingDecls.push_back(FoundDecl);
}
- if (MergeWithVar) {
- // An equivalent variable with external linkage has been found. Link
- // the two declarations, then merge them.
- Importer.MapImported(D, MergeWithVar);
- updateFlags(D, MergeWithVar);
-
- if (VarDecl *DDef = D->getDefinition()) {
- if (VarDecl *ExistingDef = MergeWithVar->getDefinition()) {
- Importer.ToDiag(ExistingDef->getLocation(),
- diag::err_odr_variable_multiple_def)
- << Name;
- Importer.FromDiag(DDef->getLocation(), diag::note_odr_defined_here);
- } else {
- Expr *Init = Importer.Import(DDef->getInit());
- MergeWithVar->setInit(Init);
- if (DDef->isInitKnownICE()) {
- EvaluatedStmt *Eval = MergeWithVar->ensureEvaluatedStmt();
- Eval->CheckedICE = true;
- Eval->IsICE = DDef->isInitICE();
- }
- }
- }
-
- return MergeWithVar;
- }
-
if (!ConflictingDecls.empty()) {
Name = Importer.HandleNameConflict(Name, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
- // Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ QualType ToType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ SourceLocation ToInnerLocStart;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ D->getType(), D->getTypeSourceInfo(), D->getInnerLocStart(),
+ D->getQualifierLoc()))
+ std::tie(ToType, ToTypeSourceInfo, ToInnerLocStart, ToQualifierLoc) = *Imp;
+ else
+ return Imp.takeError();
// Create the imported variable.
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
VarDecl *ToVar;
if (GetImportedOrCreateDecl(ToVar, D, Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()), Loc,
- Name.getAsIdentifierInfo(), T, TInfo,
+ ToInnerLocStart, Loc,
+ Name.getAsIdentifierInfo(),
+ ToType, ToTypeSourceInfo,
D->getStorageClass()))
return ToVar;
- ToVar->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ ToVar->setQualifierInfo(ToQualifierLoc);
ToVar->setAccess(D->getAccess());
ToVar->setLexicalDeclContext(LexicalDC);
- // Templated declarations should never appear in the enclosing DeclContext.
- if (!D->getDescribedVarTemplate())
- LexicalDC->addDeclInternal(ToVar);
+ if (FoundByLookup) {
+ auto *Recent = const_cast<VarDecl *>(FoundByLookup->getMostRecentDecl());
+ ToVar->setPreviousDecl(Recent);
+ }
- // Merge the initializer.
- if (ImportDefinition(D, ToVar))
- return nullptr;
+ if (Error Err = ImportInitializer(D, ToVar))
+ return std::move(Err);
if (D->isConstexpr())
ToVar->setConstexpr(true);
+ if (D->getDeclContext()->containsDeclAndLoad(D))
+ DC->addDeclInternal(ToVar);
+ if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
+ LexicalDC->addDeclInternal(ToVar);
+
+ // Import the rest of the chain. I.e. import all subsequent declarations.
+ for (++RedeclIt; RedeclIt != Redecls.end(); ++RedeclIt) {
+ ExpectedDecl RedeclOrErr = import(*RedeclIt);
+ if (!RedeclOrErr)
+ return RedeclOrErr.takeError();
+ }
+
return ToVar;
}
-Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
// Parameters are created in the translation unit's context, then moved
// into the function declaration's context afterward.
DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
- // Import the name of this declaration.
- DeclarationName Name = Importer.Import(D->getDeclName());
- if (D->getDeclName() && !Name)
- return nullptr;
-
- // Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
-
- // Import the parameter's type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ DeclarationName ToDeclName;
+ SourceLocation ToLocation;
+ QualType ToType;
+ if (auto Imp = importSeq(D->getDeclName(), D->getLocation(), D->getType()))
+ std::tie(ToDeclName, ToLocation, ToType) = *Imp;
+ else
+ return Imp.takeError();
// Create the imported parameter.
ImplicitParamDecl *ToParm = nullptr;
- if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC, Loc,
- Name.getAsIdentifierInfo(), T,
- D->getParameterKind()))
+ if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
+ ToLocation, ToDeclName.getAsIdentifierInfo(),
+ ToType, D->getParameterKind()))
return ToParm;
return ToParm;
}
-Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
// Parameters are created in the translation unit's context, then moved
// into the function declaration's context afterward.
DeclContext *DC = Importer.getToContext().getTranslationUnitDecl();
- // Import the name of this declaration.
- DeclarationName Name = Importer.Import(D->getDeclName());
- if (D->getDeclName() && !Name)
- return nullptr;
-
- // Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
-
- // Import the parameter's type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ DeclarationName ToDeclName;
+ SourceLocation ToLocation, ToInnerLocStart;
+ QualType ToType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ if (auto Imp = importSeq(
+ D->getDeclName(), D->getLocation(), D->getType(), D->getInnerLocStart(),
+ D->getTypeSourceInfo()))
+ std::tie(
+ ToDeclName, ToLocation, ToType, ToInnerLocStart,
+ ToTypeSourceInfo) = *Imp;
+ else
+ return Imp.takeError();
- // Create the imported parameter.
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
ParmVarDecl *ToParm;
if (GetImportedOrCreateDecl(ToParm, D, Importer.getToContext(), DC,
- Importer.Import(D->getInnerLocStart()), Loc,
- Name.getAsIdentifierInfo(), T, TInfo,
- D->getStorageClass(),
+ ToInnerLocStart, ToLocation,
+ ToDeclName.getAsIdentifierInfo(), ToType,
+ ToTypeSourceInfo, D->getStorageClass(),
/*DefaultArg*/ nullptr))
return ToParm;
@@ -3283,21 +3732,19 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
ToParm->setKNRPromoted(D->isKNRPromoted());
- Expr *ToDefArg = nullptr;
- Expr *FromDefArg = nullptr;
if (D->hasUninstantiatedDefaultArg()) {
- FromDefArg = D->getUninstantiatedDefaultArg();
- ToDefArg = Importer.Import(FromDefArg);
- ToParm->setUninstantiatedDefaultArg(ToDefArg);
+ if (auto ToDefArgOrErr = import(D->getUninstantiatedDefaultArg()))
+ ToParm->setUninstantiatedDefaultArg(*ToDefArgOrErr);
+ else
+ return ToDefArgOrErr.takeError();
} else if (D->hasUnparsedDefaultArg()) {
ToParm->setUnparsedDefaultArg();
} else if (D->hasDefaultArg()) {
- FromDefArg = D->getDefaultArg();
- ToDefArg = Importer.Import(FromDefArg);
- ToParm->setDefaultArg(ToDefArg);
+ if (auto ToDefArgOrErr = import(D->getDefaultArg()))
+ ToParm->setDefaultArg(*ToDefArgOrErr);
+ else
+ return ToDefArgOrErr.takeError();
}
- if (FromDefArg && !ToDefArg)
- return nullptr;
if (D->isObjCMethodParameter()) {
ToParm->setObjCMethodScopeInfo(D->getFunctionScopeIndex());
@@ -3310,19 +3757,18 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
return ToParm;
}
-Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Import the major distinguishing characteristics of a method.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (auto *FoundMethod = dyn_cast<ObjCMethodDecl>(FoundDecl)) {
if (FoundMethod->isInstanceMethod() != D->isInstanceMethod())
@@ -3337,7 +3783,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// Check the number of parameters.
@@ -3348,7 +3795,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// Check parameter types.
@@ -3363,7 +3811,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
<< (*P)->getType() << (*FoundP)->getType();
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
<< (*FoundP)->getType();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
@@ -3375,7 +3824,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// FIXME: Any other bits we need to merge?
@@ -3383,18 +3833,20 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
}
}
- // Import the result type.
- QualType ResultTy = Importer.Import(D->getReturnType());
- if (ResultTy.isNull())
- return nullptr;
-
- TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
+ SourceLocation ToEndLoc;
+ QualType ToReturnType;
+ TypeSourceInfo *ToReturnTypeSourceInfo;
+ if (auto Imp = importSeq(
+ D->getEndLoc(), D->getReturnType(), D->getReturnTypeSourceInfo()))
+ std::tie(ToEndLoc, ToReturnType, ToReturnTypeSourceInfo) = *Imp;
+ else
+ return Imp.takeError();
ObjCMethodDecl *ToMethod;
if (GetImportedOrCreateDecl(
ToMethod, D, Importer.getToContext(), Loc,
- Importer.Import(D->getLocEnd()), Name.getObjCSelector(), ResultTy,
- ReturnTInfo, DC, D->isInstanceMethod(), D->isVariadic(),
+ ToEndLoc, Name.getObjCSelector(), ToReturnType,
+ ToReturnTypeSourceInfo, DC, D->isInstanceMethod(), D->isVariadic(),
D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
D->getImplementationControl(), D->hasRelatedResultType()))
return ToMethod;
@@ -3405,11 +3857,10 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Import the parameters
SmallVector<ParmVarDecl *, 5> ToParams;
for (auto *FromP : D->parameters()) {
- auto *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
- if (!ToP)
- return nullptr;
-
- ToParams.push_back(ToP);
+ if (Expected<ParmVarDecl *> ToPOrErr = import(FromP))
+ ToParams.push_back(*ToPOrErr);
+ else
+ return ToPOrErr.takeError();
}
// Set the parameters.
@@ -3418,82 +3869,99 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
ToMethod->addDeclInternal(ToParam);
}
- SmallVector<SourceLocation, 12> SelLocs;
- D->getSelectorLocs(SelLocs);
- for (auto &Loc : SelLocs)
- Loc = Importer.Import(Loc);
+ SmallVector<SourceLocation, 12> FromSelLocs;
+ D->getSelectorLocs(FromSelLocs);
+ SmallVector<SourceLocation, 12> ToSelLocs(FromSelLocs.size());
+ if (Error Err = ImportContainerChecked(FromSelLocs, ToSelLocs))
+ return std::move(Err);
- ToMethod->setMethodParams(Importer.getToContext(), ToParams, SelLocs);
+ ToMethod->setMethodParams(Importer.getToContext(), ToParams, ToSelLocs);
ToMethod->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToMethod);
return ToMethod;
}
-Decl *ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
// Import the major distinguishing characteristics of a category.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- TypeSourceInfo *BoundInfo = Importer.Import(D->getTypeSourceInfo());
- if (!BoundInfo)
- return nullptr;
+ SourceLocation ToVarianceLoc, ToLocation, ToColonLoc;
+ TypeSourceInfo *ToTypeSourceInfo;
+ if (auto Imp = importSeq(
+ D->getVarianceLoc(), D->getLocation(), D->getColonLoc(),
+ D->getTypeSourceInfo()))
+ std::tie(ToVarianceLoc, ToLocation, ToColonLoc, ToTypeSourceInfo) = *Imp;
+ else
+ return Imp.takeError();
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))
+ ToVarianceLoc, D->getIndex(),
+ ToLocation, Name.getAsIdentifierInfo(),
+ ToColonLoc, ToTypeSourceInfo))
return Result;
Result->setLexicalDeclContext(LexicalDC);
return Result;
}
-Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
// Import the major distinguishing characteristics of a category.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- auto *ToInterface =
- cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
- if (!ToInterface)
- return nullptr;
+ ObjCInterfaceDecl *ToInterface;
+ if (Error Err = importInto(ToInterface, D->getClassInterface()))
+ return std::move(Err);
// Determine if we've already encountered this category.
ObjCCategoryDecl *MergeWithCategory
= ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
ObjCCategoryDecl *ToCategory = MergeWithCategory;
if (!ToCategory) {
+ SourceLocation ToAtStartLoc, ToCategoryNameLoc;
+ SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
+ if (auto Imp = importSeq(
+ D->getAtStartLoc(), D->getCategoryNameLoc(),
+ D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
+ std::tie(
+ ToAtStartLoc, ToCategoryNameLoc,
+ ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
+ else
+ return Imp.takeError();
if (GetImportedOrCreateDecl(ToCategory, D, Importer.getToContext(), DC,
- Importer.Import(D->getAtStartLoc()), Loc,
- Importer.Import(D->getCategoryNameLoc()),
+ ToAtStartLoc, Loc,
+ ToCategoryNameLoc,
Name.getAsIdentifierInfo(), ToInterface,
/*TypeParamList=*/nullptr,
- Importer.Import(D->getIvarLBraceLoc()),
- Importer.Import(D->getIvarRBraceLoc())))
+ ToIvarLBraceLoc,
+ ToIvarRBraceLoc))
return ToCategory;
ToCategory->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToCategory);
- // Import the type parameter list after calling Imported, to avoid
+ // Import the type parameter list after MapImported, to avoid
// loops when bringing in their DeclContext.
- ToCategory->setTypeParamList(ImportObjCTypeParamList(
- D->getTypeParamList()));
+ if (auto PListOrErr = ImportObjCTypeParamList(D->getTypeParamList()))
+ ToCategory->setTypeParamList(*PListOrErr);
+ else
+ return PListOrErr.takeError();
// Import protocols
SmallVector<ObjCProtocolDecl *, 4> Protocols;
@@ -3504,45 +3972,48 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
FromProtoEnd = D->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- auto *ToProto =
- cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
- if (!ToProto)
- return nullptr;
- Protocols.push_back(ToProto);
- ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+ Protocols.push_back(*ToProtoOrErr);
+ else
+ return ToProtoOrErr.takeError();
+
+ if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+ ProtocolLocs.push_back(*ToProtoLocOrErr);
+ else
+ return ToProtoLocOrErr.takeError();
}
// 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.MapImported(D, ToCategory);
}
// Import all of the members of this category.
- ImportDeclContext(D);
+ if (Error Err = ImportDeclContext(D))
+ return std::move(Err);
// If we have an implementation, import it as well.
if (D->getImplementation()) {
- auto *Impl =
- cast_or_null<ObjCCategoryImplDecl>(
- Importer.Import(D->getImplementation()));
- if (!Impl)
- return nullptr;
-
- ToCategory->setImplementation(Impl);
+ if (Expected<ObjCCategoryImplDecl *> ToImplOrErr =
+ import(D->getImplementation()))
+ ToCategory->setImplementation(*ToImplOrErr);
+ else
+ return ToImplOrErr.takeError();
}
return ToCategory;
}
-bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
- ObjCProtocolDecl *To,
- ImportDefinitionKind Kind) {
+Error ASTNodeImporter::ImportDefinition(
+ ObjCProtocolDecl *From, ObjCProtocolDecl *To, ImportDefinitionKind Kind) {
if (To->getDefinition()) {
if (shouldForceImportDeclContext(Kind))
- ImportDeclContext(From);
- return false;
+ if (Error Err = ImportDeclContext(From))
+ return Err;
+ return Error::success();
}
// Start the protocol definition
@@ -3551,17 +4022,22 @@ bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
// Import protocols
SmallVector<ObjCProtocolDecl *, 4> Protocols;
SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCProtocolDecl::protocol_loc_iterator
- FromProtoLoc = From->protocol_loc_begin();
+ ObjCProtocolDecl::protocol_loc_iterator FromProtoLoc =
+ From->protocol_loc_begin();
for (ObjCProtocolDecl::protocol_iterator FromProto = From->protocol_begin(),
FromProtoEnd = From->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
- if (!ToProto)
- return true;
- Protocols.push_back(ToProto);
- ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+ Protocols.push_back(*ToProtoOrErr);
+ else
+ return ToProtoOrErr.takeError();
+
+ if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+ ProtocolLocs.push_back(*ToProtoLocOrErr);
+ else
+ return ToProtoLocOrErr.takeError();
+
}
// FIXME: If we're merging, make sure that the protocol list is the same.
@@ -3570,22 +4046,22 @@ bool ASTNodeImporter::ImportDefinition(ObjCProtocolDecl *From,
if (shouldForceImportDeclContext(Kind)) {
// Import all of the members of this protocol.
- ImportDeclContext(From, /*ForceImport=*/true);
+ if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+ return Err;
}
- return false;
+ return Error::success();
}
-Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
// If this protocol 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.
ObjCProtocolDecl *Definition = D->getDefinition();
if (Definition && Definition != D) {
- Decl *ImportedDef = Importer.Import(Definition);
- if (!ImportedDef)
- return nullptr;
-
- return Importer.MapImported(D, ImportedDef);
+ if (ExpectedDecl ImportedDefOrErr = import(Definition))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
// Import the major distinguishing characteristics of a protocol.
@@ -3593,14 +4069,13 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
ObjCProtocolDecl *MergeWithProtocol = nullptr;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_ObjCProtocol))
continue;
@@ -3611,9 +4086,13 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
ObjCProtocolDecl *ToProto = MergeWithProtocol;
if (!ToProto) {
+ auto ToAtBeginLocOrErr = import(D->getAtStartLoc());
+ if (!ToAtBeginLocOrErr)
+ return ToAtBeginLocOrErr.takeError();
+
if (GetImportedOrCreateDecl(ToProto, D, Importer.getToContext(), DC,
Name.getAsIdentifierInfo(), Loc,
- Importer.Import(D->getAtStartLoc()),
+ *ToAtBeginLocOrErr,
/*PrevDecl=*/nullptr))
return ToProto;
ToProto->setLexicalDeclContext(LexicalDC);
@@ -3622,29 +4101,39 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Importer.MapImported(D, ToProto);
- if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
- return nullptr;
+ if (D->isThisDeclarationADefinition())
+ if (Error Err = ImportDefinition(D, ToProto))
+ return std::move(Err);
return ToProto;
}
-Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- DeclContext *LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
+ExpectedDecl ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ ExpectedSLoc ExternLocOrErr = import(D->getExternLoc());
+ if (!ExternLocOrErr)
+ return ExternLocOrErr.takeError();
- SourceLocation ExternLoc = Importer.Import(D->getExternLoc());
- SourceLocation LangLoc = Importer.Import(D->getLocation());
+ ExpectedSLoc LangLocOrErr = import(D->getLocation());
+ if (!LangLocOrErr)
+ return LangLocOrErr.takeError();
bool HasBraces = D->hasBraces();
LinkageSpecDecl *ToLinkageSpec;
if (GetImportedOrCreateDecl(ToLinkageSpec, D, Importer.getToContext(), DC,
- ExternLoc, LangLoc, D->getLanguage(), HasBraces))
+ *ExternLocOrErr, *LangLocOrErr,
+ D->getLanguage(), HasBraces))
return ToLinkageSpec;
if (HasBraces) {
- SourceLocation RBraceLoc = Importer.Import(D->getRBraceLoc());
- ToLinkageSpec->setRBraceLoc(RBraceLoc);
+ ExpectedSLoc RBraceLocOrErr = import(D->getRBraceLoc());
+ if (!RBraceLocOrErr)
+ return RBraceLocOrErr.takeError();
+ ToLinkageSpec->setRBraceLoc(*RBraceLocOrErr);
}
ToLinkageSpec->setLexicalDeclContext(LexicalDC);
@@ -3653,24 +4142,31 @@ Decl *ASTNodeImporter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
return ToLinkageSpec;
}
-Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD = nullptr;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- DeclarationNameInfo NameInfo(Name,
- Importer.Import(D->getNameInfo().getLoc()));
- ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+ SourceLocation ToLoc, ToUsingLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc()))
+ std::tie(ToLoc, ToUsingLoc, ToQualifierLoc) = *Imp;
+ else
+ return Imp.takeError();
+
+ DeclarationNameInfo NameInfo(Name, ToLoc);
+ if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+ return std::move(Err);
UsingDecl *ToUsing;
if (GetImportedOrCreateDecl(ToUsing, D, Importer.getToContext(), DC,
- Importer.Import(D->getUsingLoc()),
- Importer.Import(D->getQualifierLoc()), NameInfo,
+ ToUsingLoc, ToQualifierLoc, NameInfo,
D->hasTypename()))
return ToUsing;
@@ -3679,48 +4175,45 @@ Decl *ASTNodeImporter::VisitUsingDecl(UsingDecl *D) {
if (NamedDecl *FromPattern =
Importer.getFromContext().getInstantiatedFromUsingDecl(D)) {
- if (auto *ToPattern =
- dyn_cast_or_null<NamedDecl>(Importer.Import(FromPattern)))
- Importer.getToContext().setInstantiatedFromUsingDecl(ToUsing, ToPattern);
+ if (Expected<NamedDecl *> ToPatternOrErr = import(FromPattern))
+ Importer.getToContext().setInstantiatedFromUsingDecl(
+ ToUsing, *ToPatternOrErr);
else
- return nullptr;
+ return ToPatternOrErr.takeError();
}
- for (auto *FromShadow : D->shadows()) {
- if (auto *ToShadow =
- dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromShadow)))
- ToUsing->addShadowDecl(ToShadow);
+ for (UsingShadowDecl *FromShadow : D->shadows()) {
+ if (Expected<UsingShadowDecl *> ToShadowOrErr = import(FromShadow))
+ ToUsing->addShadowDecl(*ToShadowOrErr);
else
- // FIXME: We return a nullptr here but the definition is already created
+ // FIXME: We return error here but the definition is already created
// and available with lookups. How to fix this?..
- return nullptr;
+ return ToShadowOrErr.takeError();
}
return ToUsing;
}
-Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD = nullptr;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- auto *ToUsing = dyn_cast_or_null<UsingDecl>(
- Importer.Import(D->getUsingDecl()));
- if (!ToUsing)
- return nullptr;
+ Expected<UsingDecl *> ToUsingOrErr = import(D->getUsingDecl());
+ if (!ToUsingOrErr)
+ return ToUsingOrErr.takeError();
- auto *ToTarget = dyn_cast_or_null<NamedDecl>(
- Importer.Import(D->getTargetDecl()));
- if (!ToTarget)
- return nullptr;
+ Expected<NamedDecl *> ToTargetOrErr = import(D->getTargetDecl());
+ if (!ToTargetOrErr)
+ return ToTargetOrErr.takeError();
UsingShadowDecl *ToShadow;
if (GetImportedOrCreateDecl(ToShadow, D, Importer.getToContext(), DC, Loc,
- ToUsing, ToTarget))
+ *ToUsingOrErr, *ToTargetOrErr))
return ToShadow;
ToShadow->setLexicalDeclContext(LexicalDC);
@@ -3728,14 +4221,13 @@ Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
if (UsingShadowDecl *FromPattern =
Importer.getFromContext().getInstantiatedFromUsingShadowDecl(D)) {
- if (auto *ToPattern =
- dyn_cast_or_null<UsingShadowDecl>(Importer.Import(FromPattern)))
- Importer.getToContext().setInstantiatedFromUsingShadowDecl(ToShadow,
- ToPattern);
+ if (Expected<UsingShadowDecl *> ToPatternOrErr = import(FromPattern))
+ Importer.getToContext().setInstantiatedFromUsingShadowDecl(
+ ToShadow, *ToPatternOrErr);
else
- // FIXME: We return a nullptr here but the definition is already created
+ // FIXME: We return error here but the definition is already created
// and available with lookups. How to fix this?..
- return nullptr;
+ return ToPatternOrErr.takeError();
}
LexicalDC->addDeclInternal(ToShadow);
@@ -3743,32 +4235,40 @@ Decl *ASTNodeImporter::VisitUsingShadowDecl(UsingShadowDecl *D) {
return ToShadow;
}
-Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD = nullptr;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- DeclContext *ToComAncestor = Importer.ImportContext(D->getCommonAncestor());
- if (!ToComAncestor)
- return nullptr;
-
- auto *ToNominated = cast_or_null<NamespaceDecl>(
- Importer.Import(D->getNominatedNamespace()));
- if (!ToNominated)
- return nullptr;
+ auto ToComAncestorOrErr = Importer.ImportContext(D->getCommonAncestor());
+ if (!ToComAncestorOrErr)
+ return ToComAncestorOrErr.takeError();
+
+ NamespaceDecl *ToNominatedNamespace;
+ SourceLocation ToUsingLoc, ToNamespaceKeyLocation, ToIdentLocation;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ D->getNominatedNamespace(), D->getUsingLoc(),
+ D->getNamespaceKeyLocation(), D->getQualifierLoc(),
+ D->getIdentLocation()))
+ std::tie(
+ ToNominatedNamespace, ToUsingLoc, ToNamespaceKeyLocation,
+ ToQualifierLoc, ToIdentLocation) = *Imp;
+ else
+ return Imp.takeError();
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))
+ ToUsingLoc,
+ ToNamespaceKeyLocation,
+ ToQualifierLoc,
+ ToIdentLocation,
+ ToNominatedNamespace, *ToComAncestorOrErr))
return ToUsingDir;
ToUsingDir->setLexicalDeclContext(LexicalDC);
@@ -3777,25 +4277,34 @@ Decl *ASTNodeImporter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
return ToUsingDir;
}
-Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl(
+ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingValueDecl(
UnresolvedUsingValueDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD = nullptr;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
- DeclarationNameInfo NameInfo(Name, Importer.Import(D->getNameInfo().getLoc()));
- ImportDeclarationNameLoc(D->getNameInfo(), NameInfo);
+ SourceLocation ToLoc, ToUsingLoc, ToEllipsisLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ D->getNameInfo().getLoc(), D->getUsingLoc(), D->getQualifierLoc(),
+ D->getEllipsisLoc()))
+ std::tie(ToLoc, ToUsingLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
+ else
+ return Imp.takeError();
+
+ DeclarationNameInfo NameInfo(Name, ToLoc);
+ if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
+ return std::move(Err);
UnresolvedUsingValueDecl *ToUsingValue;
if (GetImportedOrCreateDecl(ToUsingValue, D, Importer.getToContext(), DC,
- Importer.Import(D->getUsingLoc()),
- Importer.Import(D->getQualifierLoc()), NameInfo,
- Importer.Import(D->getEllipsisLoc())))
+ ToUsingLoc, ToQualifierLoc, NameInfo,
+ ToEllipsisLoc))
return ToUsingValue;
ToUsingValue->setAccess(D->getAccess());
@@ -3805,23 +4314,30 @@ Decl *ASTNodeImporter::VisitUnresolvedUsingValueDecl(
return ToUsingValue;
}
-Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
+ExpectedDecl ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
UnresolvedUsingTypenameDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD = nullptr;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
+ SourceLocation ToUsingLoc, ToTypenameLoc, ToEllipsisLoc;
+ NestedNameSpecifierLoc ToQualifierLoc;
+ if (auto Imp = importSeq(
+ D->getUsingLoc(), D->getTypenameLoc(), D->getQualifierLoc(),
+ D->getEllipsisLoc()))
+ std::tie(ToUsingLoc, ToTypenameLoc, ToQualifierLoc, ToEllipsisLoc) = *Imp;
+ else
+ return Imp.takeError();
+
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())))
+ ToUsingLoc, ToTypenameLoc,
+ ToQualifierLoc, Loc, Name, ToEllipsisLoc))
return ToUsing;
ToUsing->setAccess(D->getAccess());
@@ -3831,16 +4347,17 @@ Decl *ASTNodeImporter::VisitUnresolvedUsingTypenameDecl(
return ToUsing;
}
-bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
- ObjCInterfaceDecl *To,
- ImportDefinitionKind Kind) {
+
+Error ASTNodeImporter::ImportDefinition(
+ ObjCInterfaceDecl *From, ObjCInterfaceDecl *To, ImportDefinitionKind Kind) {
if (To->getDefinition()) {
// Check consistency of superclass.
ObjCInterfaceDecl *FromSuper = From->getSuperClass();
if (FromSuper) {
- FromSuper = cast_or_null<ObjCInterfaceDecl>(Importer.Import(FromSuper));
- if (!FromSuper)
- return true;
+ if (auto FromSuperOrErr = import(FromSuper))
+ FromSuper = *FromSuperOrErr;
+ else
+ return FromSuperOrErr.takeError();
}
ObjCInterfaceDecl *ToSuper = To->getSuperClass();
@@ -3865,8 +4382,9 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
}
if (shouldForceImportDeclContext(Kind))
- ImportDeclContext(From);
- return false;
+ if (Error Err = ImportDeclContext(From))
+ return Err;
+ return Error::success();
}
// Start the definition.
@@ -3874,28 +4392,32 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// If this class has a superclass, import it.
if (From->getSuperClass()) {
- TypeSourceInfo *SuperTInfo = Importer.Import(From->getSuperClassTInfo());
- if (!SuperTInfo)
- return true;
-
- To->setSuperClass(SuperTInfo);
+ if (auto SuperTInfoOrErr = import(From->getSuperClassTInfo()))
+ To->setSuperClass(*SuperTInfoOrErr);
+ else
+ return SuperTInfoOrErr.takeError();
}
// Import protocols
SmallVector<ObjCProtocolDecl *, 4> Protocols;
SmallVector<SourceLocation, 4> ProtocolLocs;
- ObjCInterfaceDecl::protocol_loc_iterator
- FromProtoLoc = From->protocol_loc_begin();
+ ObjCInterfaceDecl::protocol_loc_iterator FromProtoLoc =
+ From->protocol_loc_begin();
for (ObjCInterfaceDecl::protocol_iterator FromProto = From->protocol_begin(),
FromProtoEnd = From->protocol_end();
FromProto != FromProtoEnd;
++FromProto, ++FromProtoLoc) {
- auto *ToProto = cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
- if (!ToProto)
- return true;
- Protocols.push_back(ToProto);
- ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
+ if (Expected<ObjCProtocolDecl *> ToProtoOrErr = import(*FromProto))
+ Protocols.push_back(*ToProtoOrErr);
+ else
+ return ToProtoOrErr.takeError();
+
+ if (ExpectedSLoc ToProtoLocOrErr = import(*FromProtoLoc))
+ ProtocolLocs.push_back(*ToProtoLocOrErr);
+ else
+ return ToProtoLocOrErr.takeError();
+
}
// FIXME: If we're merging, make sure that the protocol list is the same.
@@ -3904,58 +4426,66 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// Import categories. When the categories themselves are imported, they'll
// hook themselves into this interface.
- for (auto *Cat : From->known_categories())
- Importer.Import(Cat);
+ for (auto *Cat : From->known_categories()) {
+ auto ToCatOrErr = import(Cat);
+ if (!ToCatOrErr)
+ return ToCatOrErr.takeError();
+ }
// If we have an @implementation, import it as well.
if (From->getImplementation()) {
- auto *Impl = cast_or_null<ObjCImplementationDecl>(
- Importer.Import(From->getImplementation()));
- if (!Impl)
- return true;
-
- To->setImplementation(Impl);
+ if (Expected<ObjCImplementationDecl *> ToImplOrErr =
+ import(From->getImplementation()))
+ To->setImplementation(*ToImplOrErr);
+ else
+ return ToImplOrErr.takeError();
}
if (shouldForceImportDeclContext(Kind)) {
// Import all of the members of this class.
- ImportDeclContext(From, /*ForceImport=*/true);
+ if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
+ return Err;
}
- return false;
+ return Error::success();
}
-ObjCTypeParamList *
+Expected<ObjCTypeParamList *>
ASTNodeImporter::ImportObjCTypeParamList(ObjCTypeParamList *list) {
if (!list)
return nullptr;
SmallVector<ObjCTypeParamDecl *, 4> toTypeParams;
- for (auto fromTypeParam : *list) {
- auto *toTypeParam = cast_or_null<ObjCTypeParamDecl>(
- Importer.Import(fromTypeParam));
- if (!toTypeParam)
- return nullptr;
-
- toTypeParams.push_back(toTypeParam);
+ for (auto *fromTypeParam : *list) {
+ if (auto toTypeParamOrErr = import(fromTypeParam))
+ toTypeParams.push_back(*toTypeParamOrErr);
+ else
+ return toTypeParamOrErr.takeError();
}
+ auto LAngleLocOrErr = import(list->getLAngleLoc());
+ if (!LAngleLocOrErr)
+ return LAngleLocOrErr.takeError();
+
+ auto RAngleLocOrErr = import(list->getRAngleLoc());
+ if (!RAngleLocOrErr)
+ return RAngleLocOrErr.takeError();
+
return ObjCTypeParamList::create(Importer.getToContext(),
- Importer.Import(list->getLAngleLoc()),
+ *LAngleLocOrErr,
toTypeParams,
- Importer.Import(list->getRAngleLoc()));
+ *RAngleLocOrErr);
}
-Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// If this class 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.
ObjCInterfaceDecl *Definition = D->getDefinition();
if (Definition && Definition != D) {
- Decl *ImportedDef = Importer.Import(Definition);
- if (!ImportedDef)
- return nullptr;
-
- return Importer.MapImported(D, ImportedDef);
+ if (ExpectedDecl ImportedDefOrErr = import(Definition))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
// Import the major distinguishing characteristics of an @interface.
@@ -3963,15 +4493,14 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Look for an existing interface with the same name.
ObjCInterfaceDecl *MergeWithIface = nullptr;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
continue;
@@ -3983,9 +4512,13 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
// Create an interface declaration, if one does not already exist.
ObjCInterfaceDecl *ToIface = MergeWithIface;
if (!ToIface) {
+ ExpectedSLoc AtBeginLocOrErr = import(D->getAtStartLoc());
+ if (!AtBeginLocOrErr)
+ return AtBeginLocOrErr.takeError();
+
if (GetImportedOrCreateDecl(
ToIface, D, Importer.getToContext(), DC,
- Importer.Import(D->getAtStartLoc()), Name.getAsIdentifierInfo(),
+ *AtBeginLocOrErr, Name.getAsIdentifierInfo(),
/*TypeParamList=*/nullptr,
/*PrevDecl=*/nullptr, Loc, D->isImplicitInterfaceDecl()))
return ToIface;
@@ -3993,91 +4526,99 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
LexicalDC->addDeclInternal(ToIface);
}
Importer.MapImported(D, ToIface);
- // Import the type parameter list after calling Imported, to avoid
+ // Import the type parameter list after MapImported, to avoid
// loops when bringing in their DeclContext.
- ToIface->setTypeParamList(ImportObjCTypeParamList(
- D->getTypeParamListAsWritten()));
+ if (auto ToPListOrErr =
+ ImportObjCTypeParamList(D->getTypeParamListAsWritten()))
+ ToIface->setTypeParamList(*ToPListOrErr);
+ else
+ return ToPListOrErr.takeError();
- if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
- return nullptr;
+ if (D->isThisDeclarationADefinition())
+ if (Error Err = ImportDefinition(D, ToIface))
+ return std::move(Err);
return ToIface;
}
-Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
- auto *Category = cast_or_null<ObjCCategoryDecl>(
- Importer.Import(D->getCategoryDecl()));
- if (!Category)
- return nullptr;
+ExpectedDecl
+ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
+ ObjCCategoryDecl *Category;
+ if (Error Err = importInto(Category, D->getCategoryDecl()))
+ return std::move(Err);
ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
if (!ToImpl) {
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- if (!DC)
- return nullptr;
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ SourceLocation ToLocation, ToAtStartLoc, ToCategoryNameLoc;
+ if (auto Imp = importSeq(
+ D->getLocation(), D->getAtStartLoc(), D->getCategoryNameLoc()))
+ std::tie(ToLocation, ToAtStartLoc, ToCategoryNameLoc) = *Imp;
+ else
+ return Imp.takeError();
- SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
if (GetImportedOrCreateDecl(
ToImpl, D, Importer.getToContext(), DC,
Importer.Import(D->getIdentifier()), Category->getClassInterface(),
- Importer.Import(D->getLocation()),
- Importer.Import(D->getAtStartLoc()), CategoryNameLoc))
+ ToLocation, ToAtStartLoc, ToCategoryNameLoc))
return ToImpl;
- DeclContext *LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
-
- ToImpl->setLexicalDeclContext(LexicalDC);
- }
-
+ ToImpl->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToImpl);
Category->setImplementation(ToImpl);
}
Importer.MapImported(D, ToImpl);
- ImportDeclContext(D);
+ if (Error Err = ImportDeclContext(D))
+ return std::move(Err);
+
return ToImpl;
}
-Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
// Find the corresponding interface.
- auto *Iface = cast_or_null<ObjCInterfaceDecl>(
- Importer.Import(D->getClassInterface()));
- if (!Iface)
- return nullptr;
+ ObjCInterfaceDecl *Iface;
+ if (Error Err = importInto(Iface, D->getClassInterface()))
+ return std::move(Err);
// Import the superclass, if any.
- ObjCInterfaceDecl *Super = nullptr;
- if (D->getSuperClass()) {
- Super = cast_or_null<ObjCInterfaceDecl>(
- Importer.Import(D->getSuperClass()));
- if (!Super)
- return nullptr;
- }
+ ObjCInterfaceDecl *Super;
+ if (Error Err = importInto(Super, D->getSuperClass()))
+ return std::move(Err);
ObjCImplementationDecl *Impl = Iface->getImplementation();
if (!Impl) {
// We haven't imported an implementation yet. Create a new @implementation
// now.
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ SourceLocation ToLocation, ToAtStartLoc, ToSuperClassLoc;
+ SourceLocation ToIvarLBraceLoc, ToIvarRBraceLoc;
+ if (auto Imp = importSeq(
+ D->getLocation(), D->getAtStartLoc(), D->getSuperClassLoc(),
+ D->getIvarLBraceLoc(), D->getIvarRBraceLoc()))
+ std::tie(
+ ToLocation, ToAtStartLoc, ToSuperClassLoc,
+ ToIvarLBraceLoc, ToIvarRBraceLoc) = *Imp;
+ else
+ return Imp.takeError();
+
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())))
+ DC, Iface, Super,
+ ToLocation,
+ ToAtStartLoc,
+ ToSuperClassLoc,
+ ToIvarLBraceLoc,
+ ToIvarRBraceLoc))
return Impl;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- DeclContext *LexicalDC
- = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
- Impl->setLexicalDeclContext(LexicalDC);
- }
+ Impl->setLexicalDeclContext(LexicalDC);
// Associate the implementation with the class it implements.
Iface->setImplementation(Impl);
@@ -4110,30 +4651,31 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
else
Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_missing_superclass);
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
}
// Import all of the members of this @implementation.
- ImportDeclContext(D);
+ if (Error Err = ImportDeclContext(D))
+ return std::move(Err);
return Impl;
}
-Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Import the major distinguishing characteristics of an @property.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
// Check whether we have already imported this property.
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (auto *FoundProp = dyn_cast<ObjCPropertyDecl>(FoundDecl)) {
// Check property types.
@@ -4143,7 +4685,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
<< Name << D->getType() << FoundProp->getType();
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// FIXME: Check property attributes, getters, setters, etc.?
@@ -4154,79 +4697,88 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
}
}
- // Import the type.
- TypeSourceInfo *TSI = Importer.Import(D->getTypeSourceInfo());
- if (!TSI)
- return nullptr;
+ QualType ToType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ SourceLocation ToAtLoc, ToLParenLoc;
+ if (auto Imp = importSeq(
+ D->getType(), D->getTypeSourceInfo(), D->getAtLoc(), D->getLParenLoc()))
+ std::tie(ToType, ToTypeSourceInfo, ToAtLoc, ToLParenLoc) = *Imp;
+ else
+ return Imp.takeError();
// Create the new property.
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()))
+ Name.getAsIdentifierInfo(), ToAtLoc,
+ ToLParenLoc, ToType,
+ ToTypeSourceInfo, D->getPropertyImplementation()))
return ToProperty;
+ Selector ToGetterName, ToSetterName;
+ SourceLocation ToGetterNameLoc, ToSetterNameLoc;
+ ObjCMethodDecl *ToGetterMethodDecl, *ToSetterMethodDecl;
+ ObjCIvarDecl *ToPropertyIvarDecl;
+ if (auto Imp = importSeq(
+ D->getGetterName(), D->getSetterName(),
+ D->getGetterNameLoc(), D->getSetterNameLoc(),
+ D->getGetterMethodDecl(), D->getSetterMethodDecl(),
+ D->getPropertyIvarDecl()))
+ std::tie(
+ ToGetterName, ToSetterName,
+ ToGetterNameLoc, ToSetterNameLoc,
+ ToGetterMethodDecl, ToSetterMethodDecl,
+ ToPropertyIvarDecl) = *Imp;
+ else
+ return Imp.takeError();
+
ToProperty->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProperty);
ToProperty->setPropertyAttributes(D->getPropertyAttributes());
ToProperty->setPropertyAttributesAsWritten(
D->getPropertyAttributesAsWritten());
- ToProperty->setGetterName(Importer.Import(D->getGetterName()),
- Importer.Import(D->getGetterNameLoc()));
- ToProperty->setSetterName(Importer.Import(D->getSetterName()),
- Importer.Import(D->getSetterNameLoc()));
- ToProperty->setGetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
- ToProperty->setSetterMethodDecl(
- cast_or_null<ObjCMethodDecl>(Importer.Import(D->getSetterMethodDecl())));
- ToProperty->setPropertyIvarDecl(
- cast_or_null<ObjCIvarDecl>(Importer.Import(D->getPropertyIvarDecl())));
+ ToProperty->setGetterName(ToGetterName, ToGetterNameLoc);
+ ToProperty->setSetterName(ToSetterName, ToSetterNameLoc);
+ ToProperty->setGetterMethodDecl(ToGetterMethodDecl);
+ ToProperty->setSetterMethodDecl(ToSetterMethodDecl);
+ ToProperty->setPropertyIvarDecl(ToPropertyIvarDecl);
return ToProperty;
}
-Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
- auto *Property = cast_or_null<ObjCPropertyDecl>(
- Importer.Import(D->getPropertyDecl()));
- if (!Property)
- return nullptr;
-
- DeclContext *DC = Importer.ImportContext(D->getDeclContext());
- if (!DC)
- return nullptr;
+ExpectedDecl
+ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
+ ObjCPropertyDecl *Property;
+ if (Error Err = importInto(Property, D->getPropertyDecl()))
+ return std::move(Err);
- // Import the lexical declaration context.
- DeclContext *LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
- }
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
- auto *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
- if (!InImpl)
- return nullptr;
+ auto *InImpl = cast<ObjCImplDecl>(LexicalDC);
// Import the ivar (for an @synthesize).
ObjCIvarDecl *Ivar = nullptr;
- if (D->getPropertyIvarDecl()) {
- Ivar = cast_or_null<ObjCIvarDecl>(
- Importer.Import(D->getPropertyIvarDecl()));
- if (!Ivar)
- return nullptr;
- }
+ if (Error Err = importInto(Ivar, D->getPropertyIvarDecl()))
+ return std::move(Err);
ObjCPropertyImplDecl *ToImpl
= InImpl->FindPropertyImplDecl(Property->getIdentifier(),
Property->getQueryKind());
if (!ToImpl) {
+ SourceLocation ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc;
+ if (auto Imp = importSeq(
+ D->getBeginLoc(), D->getLocation(), D->getPropertyIvarDeclLoc()))
+ std::tie(ToBeginLoc, ToLocation, ToPropertyIvarDeclLoc) = *Imp;
+ else
+ return Imp.takeError();
+
if (GetImportedOrCreateDecl(ToImpl, D, Importer.getToContext(), DC,
- Importer.Import(D->getLocStart()),
- Importer.Import(D->getLocation()), Property,
+ ToBeginLoc,
+ ToLocation, Property,
D->getPropertyImplementation(), Ivar,
- Importer.Import(D->getPropertyIvarDeclLoc())))
+ ToPropertyIvarDeclLoc))
return ToImpl;
ToImpl->setLexicalDeclContext(LexicalDC);
@@ -4244,7 +4796,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
diag::note_odr_objc_property_impl_kind)
<< D->getPropertyDecl()->getDeclName()
<< (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// For @synthesize, check that we have the same
@@ -4258,7 +4811,8 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
Importer.FromDiag(D->getPropertyIvarDeclLoc(),
diag::note_odr_objc_synthesize_ivar_here)
<< D->getPropertyIvarDecl()->getDeclName();
- return nullptr;
+
+ return make_error<ImportError>(ImportError::NameConflict);
}
// Merge the existing implementation with the new implementation.
@@ -4268,41 +4822,46 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
return ToImpl;
}
-Decl *ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
// For template arguments, we adopt the translation unit as our declaration
// context. This context will be fixed when the actual template declaration
// is created.
// FIXME: Import default argument.
+
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+
+ ExpectedSLoc LocationOrErr = import(D->getLocation());
+ if (!LocationOrErr)
+ return LocationOrErr.takeError();
+
TemplateTypeParmDecl *ToD = nullptr;
(void)GetImportedOrCreateDecl(
ToD, D, Importer.getToContext(),
Importer.getToContext().getTranslationUnitDecl(),
- Importer.Import(D->getLocStart()), Importer.Import(D->getLocation()),
+ *BeginLocOrErr, *LocationOrErr,
D->getDepth(), D->getIndex(), Importer.Import(D->getIdentifier()),
D->wasDeclaredWithTypename(), D->isParameterPack());
return ToD;
}
-Decl *
+ExpectedDecl
ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
- // Import the name of this declaration.
- DeclarationName Name = Importer.Import(D->getDeclName());
- if (D->getDeclName() && !Name)
- return nullptr;
-
- // Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
-
- // Import the type of this declaration.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
-
- // Import type-source information.
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- if (D->getTypeSourceInfo() && !TInfo)
- return nullptr;
+ DeclarationName ToDeclName;
+ SourceLocation ToLocation, ToInnerLocStart;
+ QualType ToType;
+ TypeSourceInfo *ToTypeSourceInfo;
+ if (auto Imp = importSeq(
+ D->getDeclName(), D->getLocation(), D->getType(), D->getTypeSourceInfo(),
+ D->getInnerLocStart()))
+ std::tie(
+ ToDeclName, ToLocation, ToType, ToTypeSourceInfo,
+ ToInnerLocStart) = *Imp;
+ else
+ return Imp.takeError();
// FIXME: Import default argument.
@@ -4310,36 +4869,39 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
(void)GetImportedOrCreateDecl(
ToD, D, Importer.getToContext(),
Importer.getToContext().getTranslationUnitDecl(),
- Importer.Import(D->getInnerLocStart()), Loc, D->getDepth(),
- D->getPosition(), Name.getAsIdentifierInfo(), T, D->isParameterPack(),
- TInfo);
+ ToInnerLocStart, ToLocation, D->getDepth(),
+ D->getPosition(), ToDeclName.getAsIdentifierInfo(), ToType,
+ D->isParameterPack(), ToTypeSourceInfo);
return ToD;
}
-Decl *
+ExpectedDecl
ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
// Import the name of this declaration.
- DeclarationName Name = Importer.Import(D->getDeclName());
- if (D->getDeclName() && !Name)
- return nullptr;
+ auto NameOrErr = import(D->getDeclName());
+ if (!NameOrErr)
+ return NameOrErr.takeError();
// Import the location of this declaration.
- SourceLocation Loc = Importer.Import(D->getLocation());
+ ExpectedSLoc LocationOrErr = import(D->getLocation());
+ if (!LocationOrErr)
+ return LocationOrErr.takeError();
// Import template parameters.
- TemplateParameterList *TemplateParams
- = ImportTemplateParameterList(D->getTemplateParameters());
- if (!TemplateParams)
- return nullptr;
+ auto TemplateParamsOrErr = ImportTemplateParameterList(
+ D->getTemplateParameters());
+ if (!TemplateParamsOrErr)
+ return TemplateParamsOrErr.takeError();
// FIXME: Import default argument.
TemplateTemplateParmDecl *ToD = nullptr;
(void)GetImportedOrCreateDecl(
ToD, D, Importer.getToContext(),
- Importer.getToContext().getTranslationUnitDecl(), Loc, D->getDepth(),
- D->getPosition(), D->isParameterPack(), Name.getAsIdentifierInfo(),
- TemplateParams);
+ Importer.getToContext().getTranslationUnitDecl(), *LocationOrErr,
+ D->getDepth(), D->getPosition(), D->isParameterPack(),
+ (*NameOrErr).getAsIdentifierInfo(),
+ *TemplateParamsOrErr);
return ToD;
}
@@ -4354,19 +4916,18 @@ static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
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.
- auto *Definition =
- cast_or_null<CXXRecordDecl>(D->getTemplatedDecl()->getDefinition());
- if (Definition && Definition != D->getTemplatedDecl()) {
- Decl *ImportedDef
- = Importer.Import(Definition->getDescribedClassTemplate());
- if (!ImportedDef)
- return nullptr;
+ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
+ bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
- return Importer.MapImported(D, ImportedDef);
+ // If this template has a definition in the translation unit we're coming
+ // from, but this particular declaration is not that definition, import the
+ // definition and map to that.
+ ClassTemplateDecl *Definition = getDefinition(D);
+ if (Definition && Definition != D && !IsFriend) {
+ if (ExpectedDecl ImportedDefOrErr = import(Definition))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
// Import the major distinguishing characteristics of this class template.
@@ -4374,40 +4935,33 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
+ ClassTemplateDecl *FoundByLookup = nullptr;
+
// We may already have a template of the same name; try to find and match it.
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
- if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary |
+ Decl::IDNS_TagFriend))
continue;
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.
- }
+ auto *FoundTemplate = dyn_cast<ClassTemplateDecl>(Found);
+ if (FoundTemplate) {
if (IsStructuralMatch(D, FoundTemplate)) {
- // The class templates structurally match; call it the same template.
-
- Importer.MapImported(D->getTemplatedDecl(),
- FoundTemplate->getTemplatedDecl());
- return Importer.MapImported(D, FoundTemplate);
+ ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+ if (D->isThisDeclarationADefinition() && TemplateWithDef) {
+ return Importer.MapImported(D, TemplateWithDef);
+ }
+ FoundByLookup = FoundTemplate;
+ break;
}
}
@@ -4421,33 +4975,61 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
}
if (!Name)
- return nullptr;
+ return make_error<ImportError>(ImportError::NameConflict);
}
CXXRecordDecl *FromTemplated = D->getTemplatedDecl();
// Create the declaration that is being templated.
- auto *ToTemplated = cast_or_null<CXXRecordDecl>(
- Importer.Import(FromTemplated));
- if (!ToTemplated)
- return nullptr;
+ CXXRecordDecl *ToTemplated;
+ if (Error Err = importInto(ToTemplated, FromTemplated))
+ return std::move(Err);
// Create the class template declaration itself.
- TemplateParameterList *TemplateParams =
- ImportTemplateParameterList(D->getTemplateParameters());
- if (!TemplateParams)
- return nullptr;
+ auto TemplateParamsOrErr = ImportTemplateParameterList(
+ D->getTemplateParameters());
+ if (!TemplateParamsOrErr)
+ return TemplateParamsOrErr.takeError();
ClassTemplateDecl *D2;
if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, Loc, Name,
- TemplateParams, ToTemplated))
+ *TemplateParamsOrErr, ToTemplated))
return D2;
ToTemplated->setDescribedClassTemplate(D2);
D2->setAccess(D->getAccess());
D2->setLexicalDeclContext(LexicalDC);
- LexicalDC->addDeclInternal(D2);
+
+ if (D->getDeclContext()->containsDeclAndLoad(D))
+ DC->addDeclInternal(D2);
+ if (DC != LexicalDC && D->getLexicalDeclContext()->containsDeclAndLoad(D))
+ LexicalDC->addDeclInternal(D2);
+
+ if (FoundByLookup) {
+ auto *Recent =
+ const_cast<ClassTemplateDecl *>(FoundByLookup->getMostRecentDecl());
+
+ // It is possible that during the import of the class template definition
+ // we start the import of a fwd friend decl of the very same class template
+ // and we add the fwd friend decl to the lookup table. But the ToTemplated
+ // had been created earlier and by that time the lookup could not find
+ // anything existing, so it has no previous decl. Later, (still during the
+ // import of the fwd friend decl) we start to import the definition again
+ // and this time the lookup finds the previous fwd friend class template.
+ // In this case we must set up the previous decl for the templated decl.
+ if (!ToTemplated->getPreviousDecl()) {
+ CXXRecordDecl *PrevTemplated =
+ FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
+ if (ToTemplated != PrevTemplated)
+ ToTemplated->setPreviousDecl(PrevTemplated);
+ }
+
+ D2->setPreviousDecl(Recent);
+ }
+
+ if (LexicalDC != DC && IsFriend)
+ DC->makeDeclVisibleInContext(D2);
if (FromTemplated->isCompleteDefinition() &&
!ToTemplated->isCompleteDefinition()) {
@@ -4457,124 +5039,173 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
return D2;
}
-Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
+ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
// If this record has a definition in the translation unit we're coming from,
// but this particular declaration is not that definition, import the
// definition and map to that.
TagDecl *Definition = D->getDefinition();
if (Definition && Definition != D) {
- Decl *ImportedDef = Importer.Import(Definition);
- if (!ImportedDef)
- return nullptr;
-
- return Importer.MapImported(D, ImportedDef);
+ if (ExpectedDecl ImportedDefOrErr = import(Definition))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
- auto *ClassTemplate =
- cast_or_null<ClassTemplateDecl>(Importer.Import(
- D->getSpecializedTemplate()));
- if (!ClassTemplate)
- return nullptr;
+ ClassTemplateDecl *ClassTemplate;
+ if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
+ return std::move(Err);
// Import the context of this declaration.
- DeclContext *DC = ClassTemplate->getDeclContext();
- if (!DC)
- return nullptr;
-
- DeclContext *LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
- }
-
- // Import the location of this declaration.
- SourceLocation StartLoc = Importer.Import(D->getLocStart());
- SourceLocation IdLoc = Importer.Import(D->getLocation());
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
// Import template arguments.
SmallVector<TemplateArgument, 2> TemplateArgs;
- if (ImportTemplateArguments(D->getTemplateArgs().data(),
- D->getTemplateArgs().size(),
- TemplateArgs))
- return nullptr;
+ if (Error Err = ImportTemplateArguments(
+ D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
+ return std::move(Err);
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
- ClassTemplateSpecializationDecl *D2
- = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
- if (D2) {
- // We already have a class template specialization with these template
- // arguments.
+ ClassTemplateSpecializationDecl *D2 = nullptr;
+ ClassTemplatePartialSpecializationDecl *PartialSpec =
+ dyn_cast<ClassTemplatePartialSpecializationDecl>(D);
+ if (PartialSpec)
+ D2 = ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
+ else
+ D2 = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
+ ClassTemplateSpecializationDecl * const PrevDecl = D2;
+ RecordDecl *FoundDef = D2 ? D2->getDefinition() : nullptr;
+ if (FoundDef) {
+ if (!D->isCompleteDefinition()) {
+ // The "From" translation unit only had a forward declaration; call it
+ // the same declaration.
+ // TODO Handle the redecl chain properly!
+ return Importer.MapImported(D, FoundDef);
+ }
- // FIXME: Check for specialization vs. instantiation errors.
+ if (IsStructuralMatch(D, FoundDef)) {
- if (RecordDecl *FoundDef = D2->getDefinition()) {
- if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
- // The record types structurally match, or the "from" translation
- // unit only had a forward declaration anyway; call it the same
- // function.
- return Importer.MapImported(D, FoundDef);
+ Importer.MapImported(D, FoundDef);
+
+ // Import those those default field initializers which have been
+ // instantiated in the "From" context, but not in the "To" context.
+ for (auto *FromField : D->fields()) {
+ auto ToOrErr = import(FromField);
+ if (!ToOrErr)
+ // FIXME: return the error?
+ consumeError(ToOrErr.takeError());
+ }
+
+ // Import those methods which have been instantiated in the
+ // "From" context, but not in the "To" context.
+ for (CXXMethodDecl *FromM : D->methods()) {
+ auto ToOrErr = import(FromM);
+ if (!ToOrErr)
+ // FIXME: return the error?
+ consumeError(ToOrErr.takeError());
}
+
+ // TODO Import instantiated default arguments.
+ // TODO Import instantiated exception specifications.
+ //
+ // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint what
+ // else could be fused during an AST merge.
+
+ return FoundDef;
}
- } else {
- // Create a new specialization.
- if (auto *PartialSpec =
- dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
- // Import TemplateArgumentListInfo
+ } else { // We either couldn't find any previous specialization in the "To"
+ // context, or we found one but without definition. Let's create a
+ // new specialization and register that at the class template.
+
+ // Import the location of this declaration.
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+ ExpectedSLoc IdLocOrErr = import(D->getLocation());
+ if (!IdLocOrErr)
+ return IdLocOrErr.takeError();
+
+ if (PartialSpec) {
+ // Import TemplateArgumentListInfo.
TemplateArgumentListInfo ToTAInfo;
const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
- if (ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
- return nullptr;
+ if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
+ return std::move(Err);
- QualType CanonInjType = Importer.Import(
- PartialSpec->getInjectedSpecializationType());
- if (CanonInjType.isNull())
- return nullptr;
+ QualType CanonInjType;
+ if (Error Err = importInto(
+ CanonInjType, PartialSpec->getInjectedSpecializationType()))
+ return std::move(Err);
CanonInjType = CanonInjType.getCanonicalType();
- TemplateParameterList *ToTPList = ImportTemplateParameterList(
- PartialSpec->getTemplateParameters());
- if (!ToTPList && PartialSpec->getTemplateParameters())
- return nullptr;
+ auto ToTPListOrErr = ImportTemplateParameterList(
+ PartialSpec->getTemplateParameters());
+ if (!ToTPListOrErr)
+ return ToTPListOrErr.takeError();
if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
- D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
- IdLoc, ToTPList, ClassTemplate,
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
- ToTAInfo, CanonInjType, nullptr))
+ ToTAInfo, CanonInjType,
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
return D2;
- } else {
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
+ // Add this partial specialization to the class template.
+ ClassTemplate->AddPartialSpecialization(
+ cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
+
+ } else { // Not a partial specialization.
if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), D->getTagKind(), DC, StartLoc,
- IdLoc, ClassTemplate, TemplateArgs, /*PrevDecl=*/nullptr))
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
+ PrevDecl))
return D2;
+
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
+ // Add this specialization to the class template.
+ ClassTemplate->AddSpecialization(D2, InsertPos);
}
D2->setSpecializationKind(D->getSpecializationKind());
- // Add this specialization to the class template.
- ClassTemplate->AddSpecialization(D2, InsertPos);
-
// Import the qualifier, if any.
- D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ if (auto LocOrErr = import(D->getQualifierLoc()))
+ D2->setQualifierInfo(*LocOrErr);
+ else
+ return LocOrErr.takeError();
if (auto *TSI = D->getTypeAsWritten()) {
- TypeSourceInfo *TInfo = Importer.Import(TSI);
- if (!TInfo)
- return nullptr;
- D2->setTypeAsWritten(TInfo);
- D2->setTemplateKeywordLoc(Importer.Import(D->getTemplateKeywordLoc()));
- D2->setExternLoc(Importer.Import(D->getExternLoc()));
+ if (auto TInfoOrErr = import(TSI))
+ D2->setTypeAsWritten(*TInfoOrErr);
+ else
+ return TInfoOrErr.takeError();
+
+ if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
+ D2->setTemplateKeywordLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
+
+ if (auto LocOrErr = import(D->getExternLoc()))
+ D2->setExternLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
}
- SourceLocation POI = Importer.Import(D->getPointOfInstantiation());
- if (POI.isValid())
- D2->setPointOfInstantiation(POI);
- else if (D->getPointOfInstantiation().isValid())
- return nullptr;
+ if (D->getPointOfInstantiation().isValid()) {
+ if (auto POIOrErr = import(D->getPointOfInstantiation()))
+ D2->setPointOfInstantiation(*POIOrErr);
+ else
+ return POIOrErr.takeError();
+ }
D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
@@ -4586,13 +5217,14 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
LexicalDC->addDeclInternal(D2);
}
}
- if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return nullptr;
+ if (D->isCompleteDefinition())
+ if (Error Err = ImportDefinition(D, D2))
+ return std::move(Err);
return D2;
}
-Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
+ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
// If this variable has a definition in the translation unit we're coming
// from,
// but this particular declaration is not that definition, import the
@@ -4600,11 +5232,11 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
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.MapImported(D, ImportedDef);
+ if (ExpectedDecl ImportedDefOrErr = import(
+ Definition->getDescribedVarTemplate()))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
// Import the major distinguishing characteristics of this variable template.
@@ -4612,8 +5244,8 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -4621,14 +5253,13 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
assert(!DC->isFunctionOrMethod() &&
"Variable templates cannot be declared at function scope");
SmallVector<NamedDecl *, 4> ConflictingDecls;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
continue;
Decl *Found = FoundDecl;
- if (auto *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
+ if (VarTemplateDecl *FoundTemplate = dyn_cast<VarTemplateDecl>(Found)) {
if (IsStructuralMatch(D, FoundTemplate)) {
// The variable templates structurally match; call it the same template.
Importer.MapImported(D->getTemplatedDecl(),
@@ -4647,29 +5278,32 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
}
if (!Name)
- return nullptr;
+ // FIXME: Is it possible to get other error than name conflict?
+ // (Put this `if` into the previous `if`?)
+ return make_error<ImportError>(ImportError::NameConflict);
VarDecl *DTemplated = D->getTemplatedDecl();
// Import the type.
- QualType T = Importer.Import(DTemplated->getType());
- if (T.isNull())
- return nullptr;
+ // FIXME: Value not used?
+ ExpectedType TypeOrErr = import(DTemplated->getType());
+ if (!TypeOrErr)
+ return TypeOrErr.takeError();
// Create the declaration that is being templated.
- auto *ToTemplated = dyn_cast_or_null<VarDecl>(Importer.Import(DTemplated));
- if (!ToTemplated)
- return nullptr;
+ VarDecl *ToTemplated;
+ if (Error Err = importInto(ToTemplated, DTemplated))
+ return std::move(Err);
// Create the variable template declaration itself.
- TemplateParameterList *TemplateParams =
- ImportTemplateParameterList(D->getTemplateParameters());
- if (!TemplateParams)
- return nullptr;
+ auto TemplateParamsOrErr = ImportTemplateParameterList(
+ D->getTemplateParameters());
+ if (!TemplateParamsOrErr)
+ return TemplateParamsOrErr.takeError();
VarTemplateDecl *ToVarTD;
if (GetImportedOrCreateDecl(ToVarTD, D, Importer.getToContext(), DC, Loc,
- Name, TemplateParams, ToTemplated))
+ Name, *TemplateParamsOrErr, ToTemplated))
return ToVarTD;
ToTemplated->setDescribedVarTemplate(ToVarTD);
@@ -4686,46 +5320,42 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
return ToVarTD;
}
-Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
+ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
VarTemplateSpecializationDecl *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.
VarDecl *Definition = D->getDefinition();
if (Definition && Definition != D) {
- Decl *ImportedDef = Importer.Import(Definition);
- if (!ImportedDef)
- return nullptr;
-
- return Importer.MapImported(D, ImportedDef);
+ if (ExpectedDecl ImportedDefOrErr = import(Definition))
+ return Importer.MapImported(D, *ImportedDefOrErr);
+ else
+ return ImportedDefOrErr.takeError();
}
- auto *VarTemplate = cast_or_null<VarTemplateDecl>(
- Importer.Import(D->getSpecializedTemplate()));
- if (!VarTemplate)
- return nullptr;
+ VarTemplateDecl *VarTemplate;
+ if (Error Err = importInto(VarTemplate, D->getSpecializedTemplate()))
+ return std::move(Err);
// Import the context of this declaration.
- DeclContext *DC = VarTemplate->getDeclContext();
- if (!DC)
- return nullptr;
-
- DeclContext *LexicalDC = DC;
- if (D->getDeclContext() != D->getLexicalDeclContext()) {
- LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
- if (!LexicalDC)
- return nullptr;
- }
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
// Import the location of this declaration.
- SourceLocation StartLoc = Importer.Import(D->getLocStart());
- SourceLocation IdLoc = Importer.Import(D->getLocation());
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+
+ auto IdLocOrErr = import(D->getLocation());
+ if (!IdLocOrErr)
+ return IdLocOrErr.takeError();
// Import template arguments.
SmallVector<TemplateArgument, 2> TemplateArgs;
- if (ImportTemplateArguments(D->getTemplateArgs().data(),
- D->getTemplateArgs().size(), TemplateArgs))
- return nullptr;
+ if (Error Err = ImportTemplateArguments(
+ D->getTemplateArgs().data(), D->getTemplateArgs().size(), TemplateArgs))
+ return std::move(Err);
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
@@ -4748,17 +5378,18 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
}
} else {
// Import the type.
- QualType T = Importer.Import(D->getType());
- if (T.isNull())
- return nullptr;
+ QualType T;
+ if (Error Err = importInto(T, D->getType()))
+ return std::move(Err);
- TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- if (D->getTypeSourceInfo() && !TInfo)
- return nullptr;
+ auto TInfoOrErr = import(D->getTypeSourceInfo());
+ if (!TInfoOrErr)
+ return TInfoOrErr.takeError();
TemplateArgumentListInfo ToTAInfo;
- if (ImportTemplateArgumentListInfo(D->getTemplateArgsInfo(), ToTAInfo))
- return nullptr;
+ if (Error Err = ImportTemplateArgumentListInfo(
+ D->getTemplateArgsInfo(), ToTAInfo))
+ return std::move(Err);
using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
// Create a new specialization.
@@ -4767,41 +5398,47 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
TemplateArgumentListInfo ArgInfos;
const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
// NOTE: FromTAArgsAsWritten and template parameter list are non-null.
- if (ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
- return nullptr;
+ if (Error Err = ImportTemplateArgumentListInfo(
+ *FromTAArgsAsWritten, ArgInfos))
+ return std::move(Err);
- TemplateParameterList *ToTPList = ImportTemplateParameterList(
- FromPartial->getTemplateParameters());
- if (!ToTPList)
- return nullptr;
+ auto ToTPListOrErr = ImportTemplateParameterList(
+ FromPartial->getTemplateParameters());
+ if (!ToTPListOrErr)
+ return ToTPListOrErr.takeError();
PartVarSpecDecl *ToPartial;
if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
- StartLoc, IdLoc, ToTPList, VarTemplate, T,
- TInfo, D->getStorageClass(), TemplateArgs,
- ArgInfos))
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
+ VarTemplate, T, *TInfoOrErr,
+ D->getStorageClass(), TemplateArgs, ArgInfos))
return ToPartial;
- auto *FromInst = FromPartial->getInstantiatedFromMember();
- auto *ToInst = cast_or_null<PartVarSpecDecl>(Importer.Import(FromInst));
- if (FromInst && !ToInst)
- return nullptr;
+ if (Expected<PartVarSpecDecl *> ToInstOrErr = import(
+ FromPartial->getInstantiatedFromMember()))
+ ToPartial->setInstantiatedFromMember(*ToInstOrErr);
+ else
+ return ToInstOrErr.takeError();
- 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,
+ if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC,
+ *BeginLocOrErr, *IdLocOrErr, VarTemplate,
+ T, *TInfoOrErr,
D->getStorageClass(), TemplateArgs))
return D2;
}
- SourceLocation POI = D->getPointOfInstantiation();
- if (POI.isValid())
- D2->setPointOfInstantiation(Importer.Import(POI));
+ if (D->getPointOfInstantiation().isValid()) {
+ if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation()))
+ D2->setPointOfInstantiation(*POIOrErr);
+ else
+ return POIOrErr.takeError();
+ }
D2->setSpecializationKind(D->getSpecializationKind());
D2->setTemplateArgsInfo(ToTAInfo);
@@ -4810,7 +5447,10 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
VarTemplate->AddSpecialization(D2, InsertPos);
// Import the qualifier, if any.
- D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
+ if (auto LocOrErr = import(D->getQualifierLoc()))
+ D2->setQualifierInfo(*LocOrErr);
+ else
+ return LocOrErr.takeError();
if (D->isConstexpr())
D2->setConstexpr(true);
@@ -4822,25 +5462,21 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
D2->setAccess(D->getAccess());
}
- // 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;
+ if (Error Err = ImportInitializer(D, D2))
+ return std::move(Err);
return D2;
}
-Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
+ExpectedDecl
+ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
DeclContext *DC, *LexicalDC;
DeclarationName Name;
SourceLocation Loc;
NamedDecl *ToD;
- if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
- return nullptr;
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
if (ToD)
return ToD;
@@ -4849,13 +5485,13 @@ Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// type, and in the same context as the function we're importing.
if (!LexicalDC->isFunctionOrMethod()) {
unsigned IDNS = Decl::IDNS_Ordinary;
- SmallVector<NamedDecl *, 2> FoundDecls;
- DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
+ auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundFunction = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
+ if (auto *FoundFunction =
+ dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
if (FoundFunction->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
if (IsStructuralMatch(D, FoundFunction)) {
@@ -4865,22 +5501,22 @@ Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
}
}
}
+ // TODO: handle conflicting names
}
}
- TemplateParameterList *Params =
- ImportTemplateParameterList(D->getTemplateParameters());
- if (!Params)
- return nullptr;
+ auto ParamsOrErr = ImportTemplateParameterList(
+ D->getTemplateParameters());
+ if (!ParamsOrErr)
+ return ParamsOrErr.takeError();
- auto *TemplatedFD =
- cast_or_null<FunctionDecl>(Importer.Import(D->getTemplatedDecl()));
- if (!TemplatedFD)
- return nullptr;
+ FunctionDecl *TemplatedFD;
+ if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl()))
+ return std::move(Err);
FunctionTemplateDecl *ToFunc;
if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name,
- Params, TemplatedFD))
+ *ParamsOrErr, TemplatedFD))
return ToFunc;
TemplatedFD->setDescribedFunctionTemplate(ToFunc);
@@ -4895,2073 +5531,2189 @@ Decl *ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// Import Statements
//----------------------------------------------------------------------------
-DeclGroupRef ASTNodeImporter::ImportDeclGroup(DeclGroupRef DG) {
- if (DG.isNull())
- return DeclGroupRef::Create(Importer.getToContext(), nullptr, 0);
- size_t NumDecls = DG.end() - DG.begin();
- SmallVector<Decl *, 1> ToDecls(NumDecls);
- auto &_Importer = this->Importer;
- std::transform(DG.begin(), DG.end(), ToDecls.begin(),
- [&_Importer](Decl *D) -> Decl * {
- return _Importer.Import(D);
- });
- return DeclGroupRef::Create(Importer.getToContext(),
- ToDecls.begin(),
- NumDecls);
+ExpectedStmt ASTNodeImporter::VisitStmt(Stmt *S) {
+ Importer.FromDiag(S->getBeginLoc(), diag::err_unsupported_ast_node)
+ << S->getStmtClassName();
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
}
-Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
- Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
- << S->getStmtClassName();
- return nullptr;
-}
-Stmt *ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
+ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
SmallVector<IdentifierInfo *, 4> Names;
for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
// ToII is nullptr when no symbolic name is given for output operand
// see ParseStmtAsm::ParseAsmOperandsOpt
- if (!ToII && S->getOutputIdentifier(I))
- return nullptr;
Names.push_back(ToII);
}
+
for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
IdentifierInfo *ToII = Importer.Import(S->getInputIdentifier(I));
// ToII is nullptr when no symbolic name is given for input operand
// see ParseStmtAsm::ParseAsmOperandsOpt
- if (!ToII && S->getInputIdentifier(I))
- return nullptr;
Names.push_back(ToII);
}
SmallVector<StringLiteral *, 4> Clobbers;
for (unsigned I = 0, E = S->getNumClobbers(); I != E; I++) {
- auto *Clobber = cast_or_null<StringLiteral>(
- Importer.Import(S->getClobberStringLiteral(I)));
- if (!Clobber)
- return nullptr;
- Clobbers.push_back(Clobber);
+ if (auto ClobberOrErr = import(S->getClobberStringLiteral(I)))
+ Clobbers.push_back(*ClobberOrErr);
+ else
+ return ClobberOrErr.takeError();
+
}
SmallVector<StringLiteral *, 4> Constraints;
for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
- auto *Output = cast_or_null<StringLiteral>(
- Importer.Import(S->getOutputConstraintLiteral(I)));
- if (!Output)
- return nullptr;
- Constraints.push_back(Output);
+ if (auto OutputOrErr = import(S->getOutputConstraintLiteral(I)))
+ Constraints.push_back(*OutputOrErr);
+ else
+ return OutputOrErr.takeError();
}
for (unsigned I = 0, E = S->getNumInputs(); I != E; I++) {
- auto *Input = cast_or_null<StringLiteral>(
- Importer.Import(S->getInputConstraintLiteral(I)));
- if (!Input)
- return nullptr;
- Constraints.push_back(Input);
+ if (auto InputOrErr = import(S->getInputConstraintLiteral(I)))
+ Constraints.push_back(*InputOrErr);
+ else
+ return InputOrErr.takeError();
}
SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs());
- if (ImportContainerChecked(S->outputs(), Exprs))
- return nullptr;
-
- if (ImportArrayChecked(S->inputs(), Exprs.begin() + S->getNumOutputs()))
- return nullptr;
-
- auto *AsmStr = cast_or_null<StringLiteral>(
- Importer.Import(S->getAsmString()));
- if (!AsmStr)
- return nullptr;
+ if (Error Err = ImportContainerChecked(S->outputs(), Exprs))
+ return std::move(Err);
+
+ if (Error Err = ImportArrayChecked(
+ S->inputs(), Exprs.begin() + S->getNumOutputs()))
+ return std::move(Err);
+
+ ExpectedSLoc AsmLocOrErr = import(S->getAsmLoc());
+ if (!AsmLocOrErr)
+ return AsmLocOrErr.takeError();
+ auto AsmStrOrErr = import(S->getAsmString());
+ if (!AsmStrOrErr)
+ return AsmStrOrErr.takeError();
+ ExpectedSLoc RParenLocOrErr = import(S->getRParenLoc());
+ if (!RParenLocOrErr)
+ return RParenLocOrErr.takeError();
return new (Importer.getToContext()) GCCAsmStmt(
- Importer.getToContext(),
- Importer.Import(S->getAsmLoc()),
- S->isSimple(),
- S->isVolatile(),
- S->getNumOutputs(),
- S->getNumInputs(),
- Names.data(),
- Constraints.data(),
- Exprs.data(),
- AsmStr,
- S->getNumClobbers(),
- Clobbers.data(),
- Importer.Import(S->getRParenLoc()));
-}
-
-Stmt *ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
- DeclGroupRef ToDG = ImportDeclGroup(S->getDeclGroup());
- for (auto *ToD : ToDG) {
- if (!ToD)
- return nullptr;
- }
- SourceLocation ToStartLoc = Importer.Import(S->getStartLoc());
- SourceLocation ToEndLoc = Importer.Import(S->getEndLoc());
- return new (Importer.getToContext()) DeclStmt(ToDG, ToStartLoc, ToEndLoc);
-}
+ Importer.getToContext(),
+ *AsmLocOrErr,
+ S->isSimple(),
+ S->isVolatile(),
+ S->getNumOutputs(),
+ S->getNumInputs(),
+ Names.data(),
+ Constraints.data(),
+ Exprs.data(),
+ *AsmStrOrErr,
+ S->getNumClobbers(),
+ Clobbers.data(),
+ *RParenLocOrErr);
+}
+
+ExpectedStmt ASTNodeImporter::VisitDeclStmt(DeclStmt *S) {
+ auto Imp = importSeq(S->getDeclGroup(), S->getBeginLoc(), S->getEndLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ DeclGroupRef ToDG;
+ SourceLocation ToBeginLoc, ToEndLoc;
+ std::tie(ToDG, ToBeginLoc, ToEndLoc) = *Imp;
+
+ return new (Importer.getToContext()) DeclStmt(ToDG, ToBeginLoc, ToEndLoc);
+}
+
+ExpectedStmt ASTNodeImporter::VisitNullStmt(NullStmt *S) {
+ ExpectedSLoc ToSemiLocOrErr = import(S->getSemiLoc());
+ if (!ToSemiLocOrErr)
+ return ToSemiLocOrErr.takeError();
+ return new (Importer.getToContext()) NullStmt(
+ *ToSemiLocOrErr, S->hasLeadingEmptyMacro());
+}
+
+ExpectedStmt ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
+ SmallVector<Stmt *, 8> ToStmts(S->size());
-Stmt *ASTNodeImporter::VisitNullStmt(NullStmt *S) {
- SourceLocation ToSemiLoc = Importer.Import(S->getSemiLoc());
- return new (Importer.getToContext()) NullStmt(ToSemiLoc,
- S->hasLeadingEmptyMacro());
-}
+ if (Error Err = ImportContainerChecked(S->body(), ToStmts))
+ return std::move(Err);
-Stmt *ASTNodeImporter::VisitCompoundStmt(CompoundStmt *S) {
- SmallVector<Stmt *, 8> ToStmts(S->size());
+ ExpectedSLoc ToLBracLocOrErr = import(S->getLBracLoc());
+ if (!ToLBracLocOrErr)
+ return ToLBracLocOrErr.takeError();
- if (ImportContainerChecked(S->body(), ToStmts))
- return nullptr;
+ ExpectedSLoc ToRBracLocOrErr = import(S->getRBracLoc());
+ if (!ToRBracLocOrErr)
+ return ToRBracLocOrErr.takeError();
- SourceLocation ToLBraceLoc = Importer.Import(S->getLBracLoc());
- SourceLocation ToRBraceLoc = Importer.Import(S->getRBracLoc());
- return CompoundStmt::Create(Importer.getToContext(), ToStmts, ToLBraceLoc,
- ToRBraceLoc);
+ return CompoundStmt::Create(
+ Importer.getToContext(), ToStmts,
+ *ToLBracLocOrErr, *ToRBracLocOrErr);
}
-Stmt *ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
- Expr *ToLHS = Importer.Import(S->getLHS());
- if (!ToLHS)
- return nullptr;
- Expr *ToRHS = Importer.Import(S->getRHS());
- if (!ToRHS && S->getRHS())
- return nullptr;
- Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
- if (!ToSubStmt && S->getSubStmt())
- return nullptr;
- SourceLocation ToCaseLoc = Importer.Import(S->getCaseLoc());
- SourceLocation ToEllipsisLoc = Importer.Import(S->getEllipsisLoc());
- SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
- auto *ToStmt = new (Importer.getToContext())
- CaseStmt(ToLHS, ToRHS, ToCaseLoc, ToEllipsisLoc, ToColonLoc);
+ExpectedStmt ASTNodeImporter::VisitCaseStmt(CaseStmt *S) {
+ auto Imp = importSeq(
+ S->getLHS(), S->getRHS(), S->getSubStmt(), S->getCaseLoc(),
+ S->getEllipsisLoc(), S->getColonLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ Expr *ToLHS, *ToRHS;
+ Stmt *ToSubStmt;
+ SourceLocation ToCaseLoc, ToEllipsisLoc, ToColonLoc;
+ std::tie(ToLHS, ToRHS, ToSubStmt, ToCaseLoc, ToEllipsisLoc, ToColonLoc) =
+ *Imp;
+
+ auto *ToStmt = CaseStmt::Create(Importer.getToContext(), ToLHS, ToRHS,
+ ToCaseLoc, ToEllipsisLoc, ToColonLoc);
ToStmt->setSubStmt(ToSubStmt);
+
return ToStmt;
}
-Stmt *ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
- SourceLocation ToDefaultLoc = Importer.Import(S->getDefaultLoc());
- SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
- Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
- if (!ToSubStmt && S->getSubStmt())
- return nullptr;
- return new (Importer.getToContext()) DefaultStmt(ToDefaultLoc, ToColonLoc,
- ToSubStmt);
-}
+ExpectedStmt ASTNodeImporter::VisitDefaultStmt(DefaultStmt *S) {
+ auto Imp = importSeq(S->getDefaultLoc(), S->getColonLoc(), S->getSubStmt());
+ if (!Imp)
+ return Imp.takeError();
-Stmt *ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
- SourceLocation ToIdentLoc = Importer.Import(S->getIdentLoc());
- auto *ToLabelDecl = cast_or_null<LabelDecl>(Importer.Import(S->getDecl()));
- if (!ToLabelDecl && S->getDecl())
- return nullptr;
- Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
- if (!ToSubStmt && S->getSubStmt())
- return nullptr;
- return new (Importer.getToContext()) LabelStmt(ToIdentLoc, ToLabelDecl,
- ToSubStmt);
-}
+ SourceLocation ToDefaultLoc, ToColonLoc;
+ Stmt *ToSubStmt;
+ std::tie(ToDefaultLoc, ToColonLoc, ToSubStmt) = *Imp;
-Stmt *ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
- SourceLocation ToAttrLoc = Importer.Import(S->getAttrLoc());
- ArrayRef<const Attr*> FromAttrs(S->getAttrs());
- SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
- if (ImportContainerChecked(FromAttrs, ToAttrs))
- return nullptr;
- Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
- if (!ToSubStmt && S->getSubStmt())
- return nullptr;
- return AttributedStmt::Create(Importer.getToContext(), ToAttrLoc,
- ToAttrs, ToSubStmt);
+ return new (Importer.getToContext()) DefaultStmt(
+ ToDefaultLoc, ToColonLoc, ToSubStmt);
}
-Stmt *ASTNodeImporter::VisitIfStmt(IfStmt *S) {
- SourceLocation ToIfLoc = Importer.Import(S->getIfLoc());
- Stmt *ToInit = Importer.Import(S->getInit());
- if (!ToInit && S->getInit())
- return nullptr;
- VarDecl *ToConditionVariable = nullptr;
- if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
- ToConditionVariable =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
- if (!ToConditionVariable)
- return nullptr;
- }
- Expr *ToCondition = Importer.Import(S->getCond());
- if (!ToCondition && S->getCond())
- return nullptr;
- Stmt *ToThenStmt = Importer.Import(S->getThen());
- if (!ToThenStmt && S->getThen())
- return nullptr;
- SourceLocation ToElseLoc = Importer.Import(S->getElseLoc());
- Stmt *ToElseStmt = Importer.Import(S->getElse());
- if (!ToElseStmt && S->getElse())
- return nullptr;
- return new (Importer.getToContext()) IfStmt(Importer.getToContext(),
- ToIfLoc, S->isConstexpr(),
- ToInit,
- ToConditionVariable,
- ToCondition, ToThenStmt,
- ToElseLoc, ToElseStmt);
+ExpectedStmt ASTNodeImporter::VisitLabelStmt(LabelStmt *S) {
+ auto Imp = importSeq(S->getIdentLoc(), S->getDecl(), S->getSubStmt());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToIdentLoc;
+ LabelDecl *ToLabelDecl;
+ Stmt *ToSubStmt;
+ std::tie(ToIdentLoc, ToLabelDecl, ToSubStmt) = *Imp;
+
+ return new (Importer.getToContext()) LabelStmt(
+ ToIdentLoc, ToLabelDecl, ToSubStmt);
}
-Stmt *ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
- Stmt *ToInit = Importer.Import(S->getInit());
- if (!ToInit && S->getInit())
- return nullptr;
- VarDecl *ToConditionVariable = nullptr;
- if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
- ToConditionVariable =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
- if (!ToConditionVariable)
- return nullptr;
- }
- Expr *ToCondition = Importer.Import(S->getCond());
- if (!ToCondition && S->getCond())
- return nullptr;
- auto *ToStmt = new (Importer.getToContext()) SwitchStmt(
- Importer.getToContext(), ToInit,
- ToConditionVariable, ToCondition);
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
+ExpectedStmt ASTNodeImporter::VisitAttributedStmt(AttributedStmt *S) {
+ ExpectedSLoc ToAttrLocOrErr = import(S->getAttrLoc());
+ if (!ToAttrLocOrErr)
+ return ToAttrLocOrErr.takeError();
+ ArrayRef<const Attr*> FromAttrs(S->getAttrs());
+ SmallVector<const Attr *, 1> ToAttrs(FromAttrs.size());
+ if (Error Err = ImportContainerChecked(FromAttrs, ToAttrs))
+ return std::move(Err);
+ ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
+ if (!ToSubStmtOrErr)
+ return ToSubStmtOrErr.takeError();
+
+ return AttributedStmt::Create(
+ Importer.getToContext(), *ToAttrLocOrErr, ToAttrs, *ToSubStmtOrErr);
+}
+
+ExpectedStmt ASTNodeImporter::VisitIfStmt(IfStmt *S) {
+ auto Imp = importSeq(
+ S->getIfLoc(), S->getInit(), S->getConditionVariable(), S->getCond(),
+ S->getThen(), S->getElseLoc(), S->getElse());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToIfLoc, ToElseLoc;
+ Stmt *ToInit, *ToThen, *ToElse;
+ VarDecl *ToConditionVariable;
+ Expr *ToCond;
+ std::tie(
+ ToIfLoc, ToInit, ToConditionVariable, ToCond, ToThen, ToElseLoc, ToElse) =
+ *Imp;
+
+ return IfStmt::Create(Importer.getToContext(), ToIfLoc, S->isConstexpr(),
+ ToInit, ToConditionVariable, ToCond, ToThen, ToElseLoc,
+ ToElse);
+}
+
+ExpectedStmt ASTNodeImporter::VisitSwitchStmt(SwitchStmt *S) {
+ auto Imp = importSeq(
+ S->getInit(), S->getConditionVariable(), S->getCond(),
+ S->getBody(), S->getSwitchLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ Stmt *ToInit, *ToBody;
+ VarDecl *ToConditionVariable;
+ Expr *ToCond;
+ SourceLocation ToSwitchLoc;
+ std::tie(ToInit, ToConditionVariable, ToCond, ToBody, ToSwitchLoc) = *Imp;
+
+ auto *ToStmt = SwitchStmt::Create(Importer.getToContext(), ToInit,
+ ToConditionVariable, ToCond);
ToStmt->setBody(ToBody);
- ToStmt->setSwitchLoc(Importer.Import(S->getSwitchLoc()));
+ ToStmt->setSwitchLoc(ToSwitchLoc);
+
// Now we have to re-chain the cases.
SwitchCase *LastChainedSwitchCase = nullptr;
for (SwitchCase *SC = S->getSwitchCaseList(); SC != nullptr;
SC = SC->getNextSwitchCase()) {
- auto *ToSC = dyn_cast_or_null<SwitchCase>(Importer.Import(SC));
- if (!ToSC)
- return nullptr;
+ Expected<SwitchCase *> ToSCOrErr = import(SC);
+ if (!ToSCOrErr)
+ return ToSCOrErr.takeError();
if (LastChainedSwitchCase)
- LastChainedSwitchCase->setNextSwitchCase(ToSC);
+ LastChainedSwitchCase->setNextSwitchCase(*ToSCOrErr);
else
- ToStmt->setSwitchCaseList(ToSC);
- LastChainedSwitchCase = ToSC;
+ ToStmt->setSwitchCaseList(*ToSCOrErr);
+ LastChainedSwitchCase = *ToSCOrErr;
}
+
return ToStmt;
}
-Stmt *ASTNodeImporter::VisitWhileStmt(WhileStmt *S) {
- VarDecl *ToConditionVariable = nullptr;
- if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
- ToConditionVariable =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
- if (!ToConditionVariable)
- return nullptr;
- }
- Expr *ToCondition = Importer.Import(S->getCond());
- if (!ToCondition && S->getCond())
- return nullptr;
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
- SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc());
- return new (Importer.getToContext()) WhileStmt(Importer.getToContext(),
- ToConditionVariable,
- ToCondition, ToBody,
- ToWhileLoc);
+ExpectedStmt ASTNodeImporter::VisitWhileStmt(WhileStmt *S) {
+ auto Imp = importSeq(
+ S->getConditionVariable(), S->getCond(), S->getBody(), S->getWhileLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ VarDecl *ToConditionVariable;
+ Expr *ToCond;
+ Stmt *ToBody;
+ SourceLocation ToWhileLoc;
+ std::tie(ToConditionVariable, ToCond, ToBody, ToWhileLoc) = *Imp;
+
+ return WhileStmt::Create(Importer.getToContext(), ToConditionVariable, ToCond,
+ ToBody, ToWhileLoc);
}
-Stmt *ASTNodeImporter::VisitDoStmt(DoStmt *S) {
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
- Expr *ToCondition = Importer.Import(S->getCond());
- if (!ToCondition && S->getCond())
- return nullptr;
- SourceLocation ToDoLoc = Importer.Import(S->getDoLoc());
- SourceLocation ToWhileLoc = Importer.Import(S->getWhileLoc());
- SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
- return new (Importer.getToContext()) DoStmt(ToBody, ToCondition,
- ToDoLoc, ToWhileLoc,
- ToRParenLoc);
+ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) {
+ auto Imp = importSeq(
+ S->getBody(), S->getCond(), S->getDoLoc(), S->getWhileLoc(),
+ S->getRParenLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ Stmt *ToBody;
+ Expr *ToCond;
+ SourceLocation ToDoLoc, ToWhileLoc, ToRParenLoc;
+ std::tie(ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc) = *Imp;
+
+ return new (Importer.getToContext()) DoStmt(
+ ToBody, ToCond, ToDoLoc, ToWhileLoc, ToRParenLoc);
}
-Stmt *ASTNodeImporter::VisitForStmt(ForStmt *S) {
- Stmt *ToInit = Importer.Import(S->getInit());
- if (!ToInit && S->getInit())
- return nullptr;
- Expr *ToCondition = Importer.Import(S->getCond());
- if (!ToCondition && S->getCond())
- return nullptr;
- VarDecl *ToConditionVariable = nullptr;
- if (VarDecl *FromConditionVariable = S->getConditionVariable()) {
- ToConditionVariable =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromConditionVariable));
- if (!ToConditionVariable)
- return nullptr;
- }
- Expr *ToInc = Importer.Import(S->getInc());
- if (!ToInc && S->getInc())
- return nullptr;
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
- SourceLocation ToForLoc = Importer.Import(S->getForLoc());
- SourceLocation ToLParenLoc = Importer.Import(S->getLParenLoc());
- SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
- return new (Importer.getToContext()) ForStmt(Importer.getToContext(),
- ToInit, ToCondition,
- ToConditionVariable,
- ToInc, ToBody,
- ToForLoc, ToLParenLoc,
- ToRParenLoc);
-}
-
-Stmt *ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
- LabelDecl *ToLabel = nullptr;
- if (LabelDecl *FromLabel = S->getLabel()) {
- ToLabel = dyn_cast_or_null<LabelDecl>(Importer.Import(FromLabel));
- if (!ToLabel)
- return nullptr;
- }
- SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc());
- SourceLocation ToLabelLoc = Importer.Import(S->getLabelLoc());
- return new (Importer.getToContext()) GotoStmt(ToLabel,
- ToGotoLoc, ToLabelLoc);
+ExpectedStmt ASTNodeImporter::VisitForStmt(ForStmt *S) {
+ auto Imp = importSeq(
+ S->getInit(), S->getCond(), S->getConditionVariable(), S->getInc(),
+ S->getBody(), S->getForLoc(), S->getLParenLoc(), S->getRParenLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ Stmt *ToInit;
+ Expr *ToCond, *ToInc;
+ VarDecl *ToConditionVariable;
+ Stmt *ToBody;
+ SourceLocation ToForLoc, ToLParenLoc, ToRParenLoc;
+ std::tie(
+ ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc,
+ ToLParenLoc, ToRParenLoc) = *Imp;
+
+ return new (Importer.getToContext()) ForStmt(
+ Importer.getToContext(),
+ ToInit, ToCond, ToConditionVariable, ToInc, ToBody, ToForLoc, ToLParenLoc,
+ ToRParenLoc);
}
-Stmt *ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
- SourceLocation ToGotoLoc = Importer.Import(S->getGotoLoc());
- SourceLocation ToStarLoc = Importer.Import(S->getStarLoc());
- Expr *ToTarget = Importer.Import(S->getTarget());
- if (!ToTarget && S->getTarget())
- return nullptr;
- return new (Importer.getToContext()) IndirectGotoStmt(ToGotoLoc, ToStarLoc,
- ToTarget);
+ExpectedStmt ASTNodeImporter::VisitGotoStmt(GotoStmt *S) {
+ auto Imp = importSeq(S->getLabel(), S->getGotoLoc(), S->getLabelLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ LabelDecl *ToLabel;
+ SourceLocation ToGotoLoc, ToLabelLoc;
+ std::tie(ToLabel, ToGotoLoc, ToLabelLoc) = *Imp;
+
+ return new (Importer.getToContext()) GotoStmt(
+ ToLabel, ToGotoLoc, ToLabelLoc);
}
-Stmt *ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
- SourceLocation ToContinueLoc = Importer.Import(S->getContinueLoc());
- return new (Importer.getToContext()) ContinueStmt(ToContinueLoc);
+ExpectedStmt ASTNodeImporter::VisitIndirectGotoStmt(IndirectGotoStmt *S) {
+ auto Imp = importSeq(S->getGotoLoc(), S->getStarLoc(), S->getTarget());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToGotoLoc, ToStarLoc;
+ Expr *ToTarget;
+ std::tie(ToGotoLoc, ToStarLoc, ToTarget) = *Imp;
+
+ return new (Importer.getToContext()) IndirectGotoStmt(
+ ToGotoLoc, ToStarLoc, ToTarget);
}
-Stmt *ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
- SourceLocation ToBreakLoc = Importer.Import(S->getBreakLoc());
- return new (Importer.getToContext()) BreakStmt(ToBreakLoc);
+ExpectedStmt ASTNodeImporter::VisitContinueStmt(ContinueStmt *S) {
+ ExpectedSLoc ToContinueLocOrErr = import(S->getContinueLoc());
+ if (!ToContinueLocOrErr)
+ return ToContinueLocOrErr.takeError();
+ return new (Importer.getToContext()) ContinueStmt(*ToContinueLocOrErr);
}
-Stmt *ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
- SourceLocation ToRetLoc = Importer.Import(S->getReturnLoc());
- Expr *ToRetExpr = Importer.Import(S->getRetValue());
- if (!ToRetExpr && S->getRetValue())
- return nullptr;
- 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,
- ToNRVOCandidate);
+ExpectedStmt ASTNodeImporter::VisitBreakStmt(BreakStmt *S) {
+ auto ToBreakLocOrErr = import(S->getBreakLoc());
+ if (!ToBreakLocOrErr)
+ return ToBreakLocOrErr.takeError();
+ return new (Importer.getToContext()) BreakStmt(*ToBreakLocOrErr);
}
-Stmt *ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
- SourceLocation ToCatchLoc = Importer.Import(S->getCatchLoc());
- VarDecl *ToExceptionDecl = nullptr;
- if (VarDecl *FromExceptionDecl = S->getExceptionDecl()) {
- ToExceptionDecl =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl));
- if (!ToExceptionDecl)
- return nullptr;
- }
- Stmt *ToHandlerBlock = Importer.Import(S->getHandlerBlock());
- if (!ToHandlerBlock && S->getHandlerBlock())
- return nullptr;
- return new (Importer.getToContext()) CXXCatchStmt(ToCatchLoc,
- ToExceptionDecl,
- ToHandlerBlock);
+ExpectedStmt ASTNodeImporter::VisitReturnStmt(ReturnStmt *S) {
+ auto Imp = importSeq(
+ S->getReturnLoc(), S->getRetValue(), S->getNRVOCandidate());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToReturnLoc;
+ Expr *ToRetValue;
+ const VarDecl *ToNRVOCandidate;
+ std::tie(ToReturnLoc, ToRetValue, ToNRVOCandidate) = *Imp;
+
+ return ReturnStmt::Create(Importer.getToContext(), ToReturnLoc, ToRetValue,
+ ToNRVOCandidate);
}
-Stmt *ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
- SourceLocation ToTryLoc = Importer.Import(S->getTryLoc());
- Stmt *ToTryBlock = Importer.Import(S->getTryBlock());
- if (!ToTryBlock && S->getTryBlock())
- return nullptr;
+ExpectedStmt ASTNodeImporter::VisitCXXCatchStmt(CXXCatchStmt *S) {
+ auto Imp = importSeq(
+ S->getCatchLoc(), S->getExceptionDecl(), S->getHandlerBlock());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToCatchLoc;
+ VarDecl *ToExceptionDecl;
+ Stmt *ToHandlerBlock;
+ std::tie(ToCatchLoc, ToExceptionDecl, ToHandlerBlock) = *Imp;
+
+ return new (Importer.getToContext()) CXXCatchStmt (
+ ToCatchLoc, ToExceptionDecl, ToHandlerBlock);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXTryStmt(CXXTryStmt *S) {
+ ExpectedSLoc ToTryLocOrErr = import(S->getTryLoc());
+ if (!ToTryLocOrErr)
+ return ToTryLocOrErr.takeError();
+
+ ExpectedStmt ToTryBlockOrErr = import(S->getTryBlock());
+ if (!ToTryBlockOrErr)
+ return ToTryBlockOrErr.takeError();
+
SmallVector<Stmt *, 1> ToHandlers(S->getNumHandlers());
for (unsigned HI = 0, HE = S->getNumHandlers(); HI != HE; ++HI) {
CXXCatchStmt *FromHandler = S->getHandler(HI);
- if (Stmt *ToHandler = Importer.Import(FromHandler))
- ToHandlers[HI] = ToHandler;
+ if (auto ToHandlerOrErr = import(FromHandler))
+ ToHandlers[HI] = *ToHandlerOrErr;
else
- return nullptr;
- }
- return CXXTryStmt::Create(Importer.getToContext(), ToTryLoc, ToTryBlock,
- ToHandlers);
-}
-
-Stmt *ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
- auto *ToRange =
- dyn_cast_or_null<DeclStmt>(Importer.Import(S->getRangeStmt()));
- if (!ToRange && S->getRangeStmt())
- return nullptr;
- auto *ToBegin =
- dyn_cast_or_null<DeclStmt>(Importer.Import(S->getBeginStmt()));
- if (!ToBegin && S->getBeginStmt())
- return nullptr;
- auto *ToEnd =
- dyn_cast_or_null<DeclStmt>(Importer.Import(S->getEndStmt()));
- if (!ToEnd && S->getEndStmt())
- return nullptr;
- Expr *ToCond = Importer.Import(S->getCond());
- if (!ToCond && S->getCond())
- return nullptr;
- Expr *ToInc = Importer.Import(S->getInc());
- if (!ToInc && S->getInc())
- return nullptr;
- auto *ToLoopVar =
- dyn_cast_or_null<DeclStmt>(Importer.Import(S->getLoopVarStmt()));
- if (!ToLoopVar && S->getLoopVarStmt())
- return nullptr;
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
- SourceLocation ToForLoc = Importer.Import(S->getForLoc());
- SourceLocation ToCoawaitLoc = Importer.Import(S->getCoawaitLoc());
- SourceLocation ToColonLoc = Importer.Import(S->getColonLoc());
- SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
- return new (Importer.getToContext()) CXXForRangeStmt(ToRange, ToBegin, ToEnd,
- ToCond, ToInc,
- ToLoopVar, ToBody,
- ToForLoc, ToCoawaitLoc,
- ToColonLoc, ToRParenLoc);
-}
-
-Stmt *ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
- Stmt *ToElem = Importer.Import(S->getElement());
- if (!ToElem && S->getElement())
- return nullptr;
- Expr *ToCollect = Importer.Import(S->getCollection());
- if (!ToCollect && S->getCollection())
- return nullptr;
- Stmt *ToBody = Importer.Import(S->getBody());
- if (!ToBody && S->getBody())
- return nullptr;
- SourceLocation ToForLoc = Importer.Import(S->getForLoc());
- SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
- return new (Importer.getToContext()) ObjCForCollectionStmt(ToElem,
- ToCollect,
- ToBody, ToForLoc,
+ return ToHandlerOrErr.takeError();
+ }
+
+ return CXXTryStmt::Create(
+ Importer.getToContext(), *ToTryLocOrErr,*ToTryBlockOrErr, ToHandlers);
+}
+
+ExpectedStmt ASTNodeImporter::VisitCXXForRangeStmt(CXXForRangeStmt *S) {
+ auto Imp1 = importSeq(
+ S->getInit(), S->getRangeStmt(), S->getBeginStmt(), S->getEndStmt(),
+ S->getCond(), S->getInc(), S->getLoopVarStmt(), S->getBody());
+ if (!Imp1)
+ return Imp1.takeError();
+ auto Imp2 = importSeq(
+ S->getForLoc(), S->getCoawaitLoc(), S->getColonLoc(), S->getRParenLoc());
+ if (!Imp2)
+ return Imp2.takeError();
+
+ DeclStmt *ToRangeStmt, *ToBeginStmt, *ToEndStmt, *ToLoopVarStmt;
+ Expr *ToCond, *ToInc;
+ Stmt *ToInit, *ToBody;
+ std::tie(
+ ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
+ ToBody) = *Imp1;
+ SourceLocation ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc;
+ std::tie(ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc) = *Imp2;
+
+ return new (Importer.getToContext()) CXXForRangeStmt(
+ ToInit, ToRangeStmt, ToBeginStmt, ToEndStmt, ToCond, ToInc, ToLoopVarStmt,
+ ToBody, ToForLoc, ToCoawaitLoc, ToColonLoc, ToRParenLoc);
+}
+
+ExpectedStmt
+ASTNodeImporter::VisitObjCForCollectionStmt(ObjCForCollectionStmt *S) {
+ auto Imp = importSeq(
+ S->getElement(), S->getCollection(), S->getBody(),
+ S->getForLoc(), S->getRParenLoc());
+ if (!Imp)
+ return Imp.takeError();
+
+ Stmt *ToElement, *ToBody;
+ Expr *ToCollection;
+ SourceLocation ToForLoc, ToRParenLoc;
+ std::tie(ToElement, ToCollection, ToBody, ToForLoc, ToRParenLoc) = *Imp;
+
+ return new (Importer.getToContext()) ObjCForCollectionStmt(ToElement,
+ ToCollection,
+ ToBody,
+ ToForLoc,
ToRParenLoc);
}
-Stmt *ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
- SourceLocation ToAtCatchLoc = Importer.Import(S->getAtCatchLoc());
- SourceLocation ToRParenLoc = Importer.Import(S->getRParenLoc());
- VarDecl *ToExceptionDecl = nullptr;
- if (VarDecl *FromExceptionDecl = S->getCatchParamDecl()) {
- ToExceptionDecl =
- dyn_cast_or_null<VarDecl>(Importer.Import(FromExceptionDecl));
- if (!ToExceptionDecl)
- return nullptr;
- }
- Stmt *ToBody = Importer.Import(S->getCatchBody());
- if (!ToBody && S->getCatchBody())
- return nullptr;
- return new (Importer.getToContext()) ObjCAtCatchStmt(ToAtCatchLoc,
- ToRParenLoc,
- ToExceptionDecl,
- ToBody);
+ExpectedStmt ASTNodeImporter::VisitObjCAtCatchStmt(ObjCAtCatchStmt *S) {
+ auto Imp = importSeq(
+ S->getAtCatchLoc(), S->getRParenLoc(), S->getCatchParamDecl(),
+ S->getCatchBody());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToAtCatchLoc, ToRParenLoc;
+ VarDecl *ToCatchParamDecl;
+ Stmt *ToCatchBody;
+ std::tie(ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody) = *Imp;
+
+ return new (Importer.getToContext()) ObjCAtCatchStmt (
+ ToAtCatchLoc, ToRParenLoc, ToCatchParamDecl, ToCatchBody);
}
-Stmt *ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
- SourceLocation ToAtFinallyLoc = Importer.Import(S->getAtFinallyLoc());
- Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyBody());
- if (!ToAtFinallyStmt && S->getFinallyBody())
- return nullptr;
- return new (Importer.getToContext()) ObjCAtFinallyStmt(ToAtFinallyLoc,
- ToAtFinallyStmt);
+ExpectedStmt ASTNodeImporter::VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
+ ExpectedSLoc ToAtFinallyLocOrErr = import(S->getAtFinallyLoc());
+ if (!ToAtFinallyLocOrErr)
+ return ToAtFinallyLocOrErr.takeError();
+ ExpectedStmt ToAtFinallyStmtOrErr = import(S->getFinallyBody());
+ if (!ToAtFinallyStmtOrErr)
+ return ToAtFinallyStmtOrErr.takeError();
+ return new (Importer.getToContext()) ObjCAtFinallyStmt(*ToAtFinallyLocOrErr,
+ *ToAtFinallyStmtOrErr);
}
-Stmt *ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
- SourceLocation ToAtTryLoc = Importer.Import(S->getAtTryLoc());
- Stmt *ToAtTryStmt = Importer.Import(S->getTryBody());
- if (!ToAtTryStmt && S->getTryBody())
- return nullptr;
+ExpectedStmt ASTNodeImporter::VisitObjCAtTryStmt(ObjCAtTryStmt *S) {
+ auto Imp = importSeq(
+ S->getAtTryLoc(), S->getTryBody(), S->getFinallyStmt());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToAtTryLoc;
+ Stmt *ToTryBody, *ToFinallyStmt;
+ std::tie(ToAtTryLoc, ToTryBody, ToFinallyStmt) = *Imp;
+
SmallVector<Stmt *, 1> ToCatchStmts(S->getNumCatchStmts());
for (unsigned CI = 0, CE = S->getNumCatchStmts(); CI != CE; ++CI) {
ObjCAtCatchStmt *FromCatchStmt = S->getCatchStmt(CI);
- if (Stmt *ToCatchStmt = Importer.Import(FromCatchStmt))
- ToCatchStmts[CI] = ToCatchStmt;
+ if (ExpectedStmt ToCatchStmtOrErr = import(FromCatchStmt))
+ ToCatchStmts[CI] = *ToCatchStmtOrErr;
else
- return nullptr;
+ return ToCatchStmtOrErr.takeError();
}
- Stmt *ToAtFinallyStmt = Importer.Import(S->getFinallyStmt());
- if (!ToAtFinallyStmt && S->getFinallyStmt())
- return nullptr;
+
return ObjCAtTryStmt::Create(Importer.getToContext(),
- ToAtTryLoc, ToAtTryStmt,
+ ToAtTryLoc, ToTryBody,
ToCatchStmts.begin(), ToCatchStmts.size(),
- ToAtFinallyStmt);
+ ToFinallyStmt);
}
-Stmt *ASTNodeImporter::VisitObjCAtSynchronizedStmt
+ExpectedStmt ASTNodeImporter::VisitObjCAtSynchronizedStmt
(ObjCAtSynchronizedStmt *S) {
- SourceLocation ToAtSynchronizedLoc =
- Importer.Import(S->getAtSynchronizedLoc());
- Expr *ToSynchExpr = Importer.Import(S->getSynchExpr());
- if (!ToSynchExpr && S->getSynchExpr())
- return nullptr;
- Stmt *ToSynchBody = Importer.Import(S->getSynchBody());
- if (!ToSynchBody && S->getSynchBody())
- return nullptr;
+ auto Imp = importSeq(
+ S->getAtSynchronizedLoc(), S->getSynchExpr(), S->getSynchBody());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToAtSynchronizedLoc;
+ Expr *ToSynchExpr;
+ Stmt *ToSynchBody;
+ std::tie(ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody) = *Imp;
+
return new (Importer.getToContext()) ObjCAtSynchronizedStmt(
ToAtSynchronizedLoc, ToSynchExpr, ToSynchBody);
}
-Stmt *ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
- SourceLocation ToAtThrowLoc = Importer.Import(S->getThrowLoc());
- Expr *ToThrow = Importer.Import(S->getThrowExpr());
- if (!ToThrow && S->getThrowExpr())
- return nullptr;
- return new (Importer.getToContext()) ObjCAtThrowStmt(ToAtThrowLoc, ToThrow);
+ExpectedStmt ASTNodeImporter::VisitObjCAtThrowStmt(ObjCAtThrowStmt *S) {
+ ExpectedSLoc ToThrowLocOrErr = import(S->getThrowLoc());
+ if (!ToThrowLocOrErr)
+ return ToThrowLocOrErr.takeError();
+ ExpectedExpr ToThrowExprOrErr = import(S->getThrowExpr());
+ if (!ToThrowExprOrErr)
+ return ToThrowExprOrErr.takeError();
+ return new (Importer.getToContext()) ObjCAtThrowStmt(
+ *ToThrowLocOrErr, *ToThrowExprOrErr);
}
-Stmt *ASTNodeImporter::VisitObjCAutoreleasePoolStmt
- (ObjCAutoreleasePoolStmt *S) {
- SourceLocation ToAtLoc = Importer.Import(S->getAtLoc());
- Stmt *ToSubStmt = Importer.Import(S->getSubStmt());
- if (!ToSubStmt && S->getSubStmt())
- return nullptr;
- return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(ToAtLoc,
- ToSubStmt);
+ExpectedStmt ASTNodeImporter::VisitObjCAutoreleasePoolStmt(
+ ObjCAutoreleasePoolStmt *S) {
+ ExpectedSLoc ToAtLocOrErr = import(S->getAtLoc());
+ if (!ToAtLocOrErr)
+ return ToAtLocOrErr.takeError();
+ ExpectedStmt ToSubStmtOrErr = import(S->getSubStmt());
+ if (!ToSubStmtOrErr)
+ return ToSubStmtOrErr.takeError();
+ return new (Importer.getToContext()) ObjCAutoreleasePoolStmt(*ToAtLocOrErr,
+ *ToSubStmtOrErr);
}
//----------------------------------------------------------------------------
// Import Expressions
//----------------------------------------------------------------------------
-Expr *ASTNodeImporter::VisitExpr(Expr *E) {
- Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
- << E->getStmtClassName();
- return nullptr;
-}
-
-Expr *ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
- QualType T = Importer.Import(E->getType());
- if (T.isNull())
- return nullptr;
-
- Expr *SubExpr = Importer.Import(E->getSubExpr());
- if (!SubExpr && E->getSubExpr())
- return nullptr;
-
- TypeSourceInfo *TInfo = Importer.Import(E->getWrittenTypeInfo());
- if (!TInfo)
- return nullptr;
+ExpectedStmt ASTNodeImporter::VisitExpr(Expr *E) {
+ Importer.FromDiag(E->getBeginLoc(), diag::err_unsupported_ast_node)
+ << E->getStmtClassName();
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
+}
+
+ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
+ auto Imp = importSeq(
+ E->getBuiltinLoc(), E->getSubExpr(), E->getWrittenTypeInfo(),
+ E->getRParenLoc(), E->getType());
+ if (!Imp)
+ return Imp.takeError();
+
+ SourceLocation ToBuiltinLoc, ToRParenLoc;
+ Expr *ToSubExpr;
+ TypeSourceInfo *ToWrittenTypeInfo;
+ QualType ToType;
+ std::tie(ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType) =
+ *Imp;
return new (Importer.getToContext()) VAArgExpr(
- Importer.Import(E->getBuiltinLoc()), SubExpr, TInfo,
- Importer.Import(E->getRParenLoc()), T, E->isMicrosoftABI());
+ ToBuiltinLoc, ToSubExpr, ToWrittenTypeInfo, ToRParenLoc, ToType,
+ E->isMicrosoftABI());
}
-Expr *ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
- QualType T = Importer.Import(E->getType());
- if (T.isNull())
- return nullptr;
- return new (Importer.getToContext()) GNUNullExpr(
- T, Importer.Import(E->