aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp17
-rw-r--r--lib/ARCMigrate/ARCMTActions.cpp7
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp7
-rw-r--r--lib/ARCMigrate/Internals.h7
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp68
-rw-r--r--lib/ARCMigrate/PlistReporter.cpp9
-rw-r--r--lib/ARCMigrate/TransAPIUses.cpp7
-rw-r--r--lib/ARCMigrate/TransARCAssign.cpp7
-rw-r--r--lib/ARCMigrate/TransAutoreleasePool.cpp7
-rw-r--r--lib/ARCMigrate/TransBlockObjCVariable.cpp7
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp14
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp12
-rw-r--r--lib/ARCMigrate/TransGCCalls.cpp7
-rw-r--r--lib/ARCMigrate/TransProperties.cpp7
-rw-r--r--lib/ARCMigrate/TransProtectedScope.cpp7
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp15
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp7
-rw-r--r--lib/ARCMigrate/TransUnusedInitDelegate.cpp7
-rw-r--r--lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp7
-rw-r--r--lib/ARCMigrate/TransformActions.cpp13
-rw-r--r--lib/ARCMigrate/Transforms.cpp14
-rw-r--r--lib/ARCMigrate/Transforms.h7
-rw-r--r--lib/AST/APValue.cpp166
-rw-r--r--lib/AST/ASTConsumer.cpp7
-rw-r--r--lib/AST/ASTContext.cpp584
-rw-r--r--lib/AST/ASTDiagnostic.cpp12
-rw-r--r--lib/AST/ASTDumper.cpp1455
-rw-r--r--lib/AST/ASTImporter.cpp1888
-rw-r--r--lib/AST/ASTImporterLookupTable.cpp32
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp387
-rw-r--r--lib/AST/ASTTypeTraits.cpp25
-rw-r--r--lib/AST/AttrImpl.cpp7
-rw-r--r--lib/AST/CXXABI.h7
-rw-r--r--lib/AST/CXXInheritance.cpp25
-rw-r--r--lib/AST/Comment.cpp7
-rw-r--r--lib/AST/CommentBriefParser.cpp7
-rw-r--r--lib/AST/CommentCommandTraits.cpp7
-rw-r--r--lib/AST/CommentLexer.cpp7
-rw-r--r--lib/AST/CommentParser.cpp7
-rw-r--r--lib/AST/CommentSema.cpp7
-rw-r--r--lib/AST/ComparisonCategories.cpp7
-rw-r--r--lib/AST/DataCollection.cpp7
-rw-r--r--lib/AST/Decl.cpp465
-rw-r--r--lib/AST/DeclBase.cpp61
-rw-r--r--lib/AST/DeclCXX.cpp264
-rw-r--r--lib/AST/DeclFriend.cpp7
-rw-r--r--lib/AST/DeclGroup.cpp7
-rw-r--r--lib/AST/DeclObjC.cpp9
-rw-r--r--lib/AST/DeclOpenMP.cpp110
-rw-r--r--lib/AST/DeclPrinter.cpp229
-rw-r--r--lib/AST/DeclTemplate.cpp50
-rw-r--r--lib/AST/DeclarationName.cpp15
-rw-r--r--lib/AST/Expr.cpp880
-rw-r--r--lib/AST/ExprCXX.cpp57
-rw-r--r--lib/AST/ExprClassification.cpp9
-rw-r--r--lib/AST/ExprConstant.cpp2310
-rw-r--r--lib/AST/ExprObjC.cpp38
-rw-r--r--lib/AST/ExternalASTMerger.cpp67
-rw-r--r--lib/AST/ExternalASTSource.cpp7
-rw-r--r--lib/AST/FormatString.cpp41
-rw-r--r--lib/AST/InheritViz.cpp7
-rw-r--r--lib/AST/ItaniumCXXABI.cpp7
-rw-r--r--lib/AST/ItaniumMangle.cpp139
-rw-r--r--lib/AST/JSONNodeDumper.cpp1569
-rw-r--r--lib/AST/Linkage.h7
-rw-r--r--lib/AST/Mangle.cpp212
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp7
-rw-r--r--lib/AST/MicrosoftMangle.cpp176
-rw-r--r--lib/AST/NSAPI.cpp7
-rw-r--r--lib/AST/NestedNameSpecifier.cpp7
-rw-r--r--lib/AST/ODRHash.cpp90
-rw-r--r--lib/AST/OpenMPClause.cpp360
-rw-r--r--lib/AST/ParentMap.cpp19
-rw-r--r--lib/AST/PrintfFormatString.cpp41
-rw-r--r--lib/AST/QualTypeNames.cpp22
-rw-r--r--lib/AST/RawCommentList.cpp7
-rw-r--r--lib/AST/RecordLayout.cpp7
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp167
-rw-r--r--lib/AST/ScanfFormatString.cpp18
-rw-r--r--lib/AST/SelectorLocationsKind.cpp7
-rw-r--r--lib/AST/Stmt.cpp91
-rw-r--r--lib/AST/StmtCXX.cpp7
-rw-r--r--lib/AST/StmtIterator.cpp7
-rw-r--r--lib/AST/StmtObjC.cpp7
-rw-r--r--lib/AST/StmtOpenMP.cpp26
-rw-r--r--lib/AST/StmtPrinter.cpp102
-rw-r--r--lib/AST/StmtProfile.cpp36
-rw-r--r--lib/AST/StmtViz.cpp7
-rw-r--r--lib/AST/TemplateBase.cpp7
-rw-r--r--lib/AST/TemplateName.cpp37
-rw-r--r--lib/AST/TextNodeDumper.cpp802
-rw-r--r--lib/AST/Type.cpp542
-rw-r--r--lib/AST/TypeLoc.cpp7
-rw-r--r--lib/AST/TypePrinter.cpp80
-rw-r--r--lib/AST/VTTBuilder.cpp7
-rw-r--r--lib/AST/VTableBuilder.cpp25
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp41
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp15
-rw-r--r--lib/ASTMatchers/Dynamic/Diagnostics.cpp7
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h30
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp7
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp57
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp7
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp104
-rw-r--r--lib/Analysis/BodyFarm.cpp40
-rw-r--r--lib/Analysis/CFG.cpp288
-rw-r--r--lib/Analysis/CFGReachabilityAnalysis.cpp7
-rw-r--r--lib/Analysis/CFGStmtMap.cpp9
-rw-r--r--lib/Analysis/CallGraph.cpp7
-rw-r--r--lib/Analysis/CloneDetection.cpp13
-rw-r--r--lib/Analysis/CocoaConventions.cpp7
-rw-r--r--lib/Analysis/CodeInjector.cpp7
-rw-r--r--lib/Analysis/ConstructionContext.cpp7
-rw-r--r--lib/Analysis/Consumed.cpp9
-rw-r--r--lib/Analysis/Dominators.cpp17
-rw-r--r--lib/Analysis/ExprMutationAnalyzer.cpp53
-rw-r--r--lib/Analysis/LiveVariables.cpp9
-rw-r--r--lib/Analysis/ObjCNoReturn.cpp7
-rw-r--r--lib/Analysis/PostOrderCFGView.cpp7
-rw-r--r--lib/Analysis/ProgramPoint.cpp225
-rw-r--r--lib/Analysis/ReachableCode.cpp31
-rw-r--r--lib/Analysis/RetainSummaryManager.cpp (renamed from lib/StaticAnalyzer/Core/RetainSummaryManager.cpp)350
-rw-r--r--lib/Analysis/ThreadSafety.cpp28
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp28
-rw-r--r--lib/Analysis/ThreadSafetyLogical.cpp7
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp7
-rw-r--r--lib/Analysis/UninitializedValues.cpp26
-rw-r--r--lib/Analysis/plugins/CheckerDependencyHandling/CheckerDependencyHandling.cpp28
-rw-r--r--lib/Analysis/plugins/CheckerDependencyHandling/CheckerDependencyHandlingAnalyzerPlugin.exports2
-rw-r--r--lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandling.cpp44
-rw-r--r--lib/Analysis/plugins/CheckerOptionHandling/CheckerOptionHandlingAnalyzerPlugin.exports2
-rw-r--r--lib/Analysis/plugins/SampleAnalyzer/MainCallChecker.cpp54
-rw-r--r--lib/Analysis/plugins/SampleAnalyzer/SampleAnalyzerPlugin.exports2
-rw-r--r--lib/Basic/Builtins.cpp44
-rw-r--r--lib/Basic/CharInfo.cpp7
-rw-r--r--lib/Basic/CodeGenOptions.cpp7
-rw-r--r--lib/Basic/Cuda.cpp76
-rw-r--r--lib/Basic/Diagnostic.cpp14
-rw-r--r--lib/Basic/DiagnosticIDs.cpp46
-rw-r--r--lib/Basic/DiagnosticOptions.cpp7
-rw-r--r--lib/Basic/FileManager.cpp172
-rw-r--r--lib/Basic/FileSystemStatCache.cpp80
-rw-r--r--lib/Basic/FixedPoint.cpp169
-rw-r--r--lib/Basic/IdentifierTable.cpp13
-rw-r--r--lib/Basic/LangOptions.cpp7
-rw-r--r--lib/Basic/MemoryBufferCache.cpp48
-rw-r--r--lib/Basic/Module.cpp24
-rw-r--r--lib/Basic/ObjCRuntime.cpp7
-rw-r--r--lib/Basic/OpenMPKinds.cpp73
-rw-r--r--lib/Basic/OperatorPrecedence.cpp7
-rw-r--r--lib/Basic/SanitizerBlacklist.cpp7
-rw-r--r--lib/Basic/SanitizerSpecialCaseList.cpp9
-rw-r--r--lib/Basic/Sanitizers.cpp30
-rw-r--r--lib/Basic/SourceLocation.cpp7
-rw-r--r--lib/Basic/SourceManager.cpp92
-rw-r--r--lib/Basic/TargetInfo.cpp27
-rw-r--r--lib/Basic/Targets.cpp52
-rw-r--r--lib/Basic/Targets.h11
-rw-r--r--lib/Basic/Targets/AArch64.cpp108
-rw-r--r--lib/Basic/Targets/AArch64.h31
-rw-r--r--lib/Basic/Targets/AMDGPU.cpp56
-rw-r--r--lib/Basic/Targets/AMDGPU.h10
-rw-r--r--lib/Basic/Targets/ARC.cpp9
-rw-r--r--lib/Basic/Targets/ARC.h7
-rw-r--r--lib/Basic/Targets/ARM.cpp157
-rw-r--r--lib/Basic/Targets/ARM.h21
-rw-r--r--lib/Basic/Targets/AVR.cpp7
-rw-r--r--lib/Basic/Targets/AVR.h7
-rw-r--r--lib/Basic/Targets/BPF.cpp11
-rw-r--r--lib/Basic/Targets/BPF.h7
-rw-r--r--lib/Basic/Targets/Hexagon.cpp7
-rw-r--r--lib/Basic/Targets/Hexagon.h7
-rw-r--r--lib/Basic/Targets/Lanai.cpp7
-rw-r--r--lib/Basic/Targets/Lanai.h7
-rw-r--r--lib/Basic/Targets/Le64.cpp7
-rw-r--r--lib/Basic/Targets/Le64.h7
-rw-r--r--lib/Basic/Targets/MSP430.cpp7
-rw-r--r--lib/Basic/Targets/MSP430.h13
-rw-r--r--lib/Basic/Targets/Mips.cpp15
-rw-r--r--lib/Basic/Targets/Mips.h9
-rw-r--r--lib/Basic/Targets/NVPTX.cpp15
-rw-r--r--lib/Basic/Targets/NVPTX.h31
-rw-r--r--lib/Basic/Targets/OSTargets.cpp86
-rw-r--r--lib/Basic/Targets/OSTargets.h194
-rw-r--r--lib/Basic/Targets/PNaCl.cpp7
-rw-r--r--lib/Basic/Targets/PNaCl.h7
-rw-r--r--lib/Basic/Targets/PPC.cpp36
-rw-r--r--lib/Basic/Targets/PPC.h87
-rw-r--r--lib/Basic/Targets/RISCV.cpp29
-rw-r--r--lib/Basic/Targets/RISCV.h21
-rw-r--r--lib/Basic/Targets/SPIR.cpp7
-rw-r--r--lib/Basic/Targets/SPIR.h8
-rw-r--r--lib/Basic/Targets/Sparc.cpp7
-rw-r--r--lib/Basic/Targets/Sparc.h9
-rw-r--r--lib/Basic/Targets/SystemZ.cpp13
-rw-r--r--lib/Basic/Targets/SystemZ.h11
-rw-r--r--lib/Basic/Targets/TCE.cpp7
-rw-r--r--lib/Basic/Targets/TCE.h7
-rw-r--r--lib/Basic/Targets/WebAssembly.cpp80
-rw-r--r--lib/Basic/Targets/WebAssembly.h21
-rw-r--r--lib/Basic/Targets/X86.cpp229
-rw-r--r--lib/Basic/Targets/X86.h33
-rw-r--r--lib/Basic/Targets/XCore.cpp7
-rw-r--r--lib/Basic/Targets/XCore.h7
-rw-r--r--lib/Basic/TokenKinds.cpp7
-rw-r--r--lib/Basic/Version.cpp21
-rw-r--r--lib/Basic/Warnings.cpp7
-rw-r--r--lib/Basic/XRayInstr.cpp7
-rw-r--r--lib/Basic/XRayLists.cpp9
-rw-r--r--lib/CodeGen/ABIInfo.h7
-rw-r--r--lib/CodeGen/Address.h7
-rw-r--r--lib/CodeGen/BackendUtil.cpp324
-rw-r--r--lib/CodeGen/CGAtomic.cpp34
-rw-r--r--lib/CodeGen/CGBlocks.cpp177
-rw-r--r--lib/CodeGen/CGBlocks.h7
-rw-r--r--lib/CodeGen/CGBuilder.h95
-rw-r--r--lib/CodeGen/CGBuiltin.cpp1751
-rw-r--r--lib/CodeGen/CGCUDANV.cpp249
-rw-r--r--lib/CodeGen/CGCUDARuntime.cpp7
-rw-r--r--lib/CodeGen/CGCUDARuntime.h16
-rw-r--r--lib/CodeGen/CGCXX.cpp54
-rw-r--r--lib/CodeGen/CGCXXABI.cpp15
-rw-r--r--lib/CodeGen/CGCXXABI.h31
-rw-r--r--lib/CodeGen/CGCall.cpp381
-rw-r--r--lib/CodeGen/CGCall.h22
-rw-r--r--lib/CodeGen/CGClass.cpp127
-rw-r--r--lib/CodeGen/CGCleanup.cpp25
-rw-r--r--lib/CodeGen/CGCleanup.h7
-rw-r--r--lib/CodeGen/CGCoroutine.cpp14
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp417
-rw-r--r--lib/CodeGen/CGDebugInfo.h45
-rw-r--r--lib/CodeGen/CGDecl.cpp630
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp104
-rw-r--r--lib/CodeGen/CGException.cpp92
-rw-r--r--lib/CodeGen/CGExpr.cpp386
-rw-r--r--lib/CodeGen/CGExprAgg.cpp125
-rw-r--r--lib/CodeGen/CGExprCXX.cpp197
-rw-r--r--lib/CodeGen/CGExprComplex.cpp35
-rw-r--r--lib/CodeGen/CGExprConstant.cpp1283
-rw-r--r--lib/CodeGen/CGExprScalar.cpp467
-rw-r--r--lib/CodeGen/CGGPUBuiltin.cpp7
-rw-r--r--lib/CodeGen/CGLoopInfo.cpp551
-rw-r--r--lib/CodeGen/CGLoopInfo.h91
-rw-r--r--lib/CodeGen/CGNonTrivialStruct.cpp225
-rw-r--r--lib/CodeGen/CGObjC.cpp324
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp317
-rw-r--r--lib/CodeGen/CGObjCMac.cpp576
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp29
-rw-r--r--lib/CodeGen/CGObjCRuntime.h40
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp37
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.h11
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp1871
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h141
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp1117
-rw-r--r--lib/CodeGen/CGOpenMPRuntimeNVPTX.h40
-rw-r--r--lib/CodeGen/CGRecordLayout.h7
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp39
-rw-r--r--lib/CodeGen/CGStmt.cpp230
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp156
-rw-r--r--lib/CodeGen/CGVTT.cpp7
-rw-r--r--lib/CodeGen/CGVTables.cpp39
-rw-r--r--lib/CodeGen/CGVTables.h7
-rw-r--r--lib/CodeGen/CGValue.h7
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp16
-rw-r--r--lib/CodeGen/CodeGenAction.cpp63
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp251
-rw-r--r--lib/CodeGen/CodeGenFunction.h176
-rw-r--r--lib/CodeGen/CodeGenModule.cpp577
-rw-r--r--lib/CodeGen/CodeGenModule.h160
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp13
-rw-r--r--lib/CodeGen/CodeGenPGO.h7
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp13
-rw-r--r--lib/CodeGen/CodeGenTBAA.h7
-rw-r--r--lib/CodeGen/CodeGenTypeCache.h7
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp18
-rw-r--r--lib/CodeGen/CodeGenTypes.h87
-rw-r--r--lib/CodeGen/ConstantEmitter.h7
-rw-r--r--lib/CodeGen/ConstantInitBuilder.cpp7
-rw-r--r--lib/CodeGen/CoverageMappingGen.cpp28
-rw-r--r--lib/CodeGen/CoverageMappingGen.h7
-rw-r--r--lib/CodeGen/EHScopeStack.h7
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp278
-rw-r--r--lib/CodeGen/MacroPPCallbacks.cpp7
-rw-r--r--lib/CodeGen/MacroPPCallbacks.h7
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp257
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp7
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp19
-rw-r--r--lib/CodeGen/PatternInit.cpp85
-rw-r--r--lib/CodeGen/PatternInit.h27
-rw-r--r--lib/CodeGen/SanitizerMetadata.cpp28
-rw-r--r--lib/CodeGen/SanitizerMetadata.h7
-rw-r--r--lib/CodeGen/SwiftCallingConv.cpp7
-rw-r--r--lib/CodeGen/TargetInfo.cpp444
-rw-r--r--lib/CodeGen/TargetInfo.h24
-rw-r--r--lib/CodeGen/VarBypassDetector.cpp7
-rw-r--r--lib/CodeGen/VarBypassDetector.h7
-rw-r--r--lib/CrossTU/CrossTranslationUnit.cpp216
-rw-r--r--lib/DirectoryWatcher/DirectoryScanner.cpp54
-rw-r--r--lib/DirectoryWatcher/DirectoryScanner.h29
-rw-r--r--lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp19
-rw-r--r--lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp353
-rw-r--r--lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp233
-rw-r--r--lib/Driver/Action.cpp7
-rw-r--r--lib/Driver/Compilation.cpp19
-rw-r--r--lib/Driver/DarwinSDKInfo.cpp7
-rw-r--r--lib/Driver/Distro.cpp12
-rw-r--r--lib/Driver/Driver.cpp215
-rw-r--r--lib/Driver/DriverOptions.cpp7
-rw-r--r--lib/Driver/InputInfo.h7
-rw-r--r--lib/Driver/Job.cpp13
-rw-r--r--lib/Driver/Multilib.cpp27
-rw-r--r--lib/Driver/Phases.cpp7
-rw-r--r--lib/Driver/SanitizerArgs.cpp291
-rw-r--r--lib/Driver/Tool.cpp7
-rw-r--r--lib/Driver/ToolChain.cpp147
-rw-r--r--lib/Driver/ToolChains/AMDGPU.cpp28
-rw-r--r--lib/Driver/ToolChains/AMDGPU.h11
-rw-r--r--lib/Driver/ToolChains/AVR.cpp129
-rw-r--r--lib/Driver/ToolChains/AVR.h30
-rw-r--r--lib/Driver/ToolChains/Ananas.cpp7
-rw-r--r--lib/Driver/ToolChains/Ananas.h7
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.cpp69
-rw-r--r--lib/Driver/ToolChains/Arch/AArch64.h7
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.cpp132
-rw-r--r--lib/Driver/ToolChains/Arch/ARM.h10
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp8
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.h7
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.cpp9
-rw-r--r--lib/Driver/ToolChains/Arch/PPC.h7
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.cpp55
-rw-r--r--lib/Driver/ToolChains/Arch/RISCV.h7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/Sparc.h7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.cpp7
-rw-r--r--lib/Driver/ToolChains/Arch/SystemZ.h7
-rw-r--r--lib/Driver/ToolChains/Arch/X86.cpp8
-rw-r--r--lib/Driver/ToolChains/Arch/X86.h7
-rw-r--r--lib/Driver/ToolChains/BareMetal.cpp9
-rw-r--r--lib/Driver/ToolChains/BareMetal.h7
-rw-r--r--lib/Driver/ToolChains/Clang.cpp559
-rw-r--r--lib/Driver/ToolChains/Clang.h9
-rw-r--r--lib/Driver/ToolChains/CloudABI.cpp7
-rw-r--r--lib/Driver/ToolChains/CloudABI.h7
-rw-r--r--lib/Driver/ToolChains/CommonArgs.cpp199
-rw-r--r--lib/Driver/ToolChains/CommonArgs.h20
-rw-r--r--lib/Driver/ToolChains/Contiki.cpp7
-rw-r--r--lib/Driver/ToolChains/Contiki.h7
-rw-r--r--lib/Driver/ToolChains/CrossWindows.cpp11
-rw-r--r--lib/Driver/ToolChains/CrossWindows.h7
-rw-r--r--lib/Driver/ToolChains/Cuda.cpp53
-rw-r--r--lib/Driver/ToolChains/Cuda.h7
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp336
-rw-r--r--lib/Driver/ToolChains/Darwin.h25
-rw-r--r--lib/Driver/ToolChains/DragonFly.cpp7
-rw-r--r--lib/Driver/ToolChains/DragonFly.h7
-rw-r--r--lib/Driver/ToolChains/FreeBSD.cpp9
-rw-r--r--lib/Driver/ToolChains/FreeBSD.h7
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp68
-rw-r--r--lib/Driver/ToolChains/Fuchsia.h7
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp206
-rw-r--r--lib/Driver/ToolChains/Gnu.h7
-rw-r--r--lib/Driver/ToolChains/HIP.cpp134
-rw-r--r--lib/Driver/ToolChains/HIP.h7
-rw-r--r--lib/Driver/ToolChains/Haiku.cpp7
-rw-r--r--lib/Driver/ToolChains/Haiku.h7
-rw-r--r--lib/Driver/ToolChains/Hexagon.cpp13
-rw-r--r--lib/Driver/ToolChains/Hexagon.h7
-rw-r--r--lib/Driver/ToolChains/Hurd.cpp7
-rw-r--r--lib/Driver/ToolChains/Hurd.h7
-rw-r--r--lib/Driver/ToolChains/Lanai.h7
-rw-r--r--lib/Driver/ToolChains/Linux.cpp91
-rw-r--r--lib/Driver/ToolChains/Linux.h8
-rw-r--r--lib/Driver/ToolChains/MSP430.cpp7
-rw-r--r--lib/Driver/ToolChains/MSP430.h11
-rw-r--r--lib/Driver/ToolChains/MSVC.cpp43
-rw-r--r--lib/Driver/ToolChains/MSVC.h7
-rw-r--r--lib/Driver/ToolChains/MinGW.cpp38
-rw-r--r--lib/Driver/ToolChains/MinGW.h7
-rw-r--r--lib/Driver/ToolChains/Minix.cpp7
-rw-r--r--lib/Driver/ToolChains/Minix.h7
-rw-r--r--lib/Driver/ToolChains/MipsLinux.cpp27
-rw-r--r--lib/Driver/ToolChains/MipsLinux.h12
-rw-r--r--lib/Driver/ToolChains/Myriad.cpp7
-rw-r--r--lib/Driver/ToolChains/Myriad.h7
-rw-r--r--lib/Driver/ToolChains/NaCl.cpp7
-rw-r--r--lib/Driver/ToolChains/NaCl.h7
-rw-r--r--lib/Driver/ToolChains/NetBSD.cpp37
-rw-r--r--lib/Driver/ToolChains/NetBSD.h7
-rw-r--r--lib/Driver/ToolChains/OpenBSD.cpp15
-rw-r--r--lib/Driver/ToolChains/OpenBSD.h7
-rw-r--r--lib/Driver/ToolChains/PPCLinux.cpp31
-rw-r--r--lib/Driver/ToolChains/PPCLinux.h33
-rw-r--r--lib/Driver/ToolChains/PS4CPU.cpp9
-rw-r--r--lib/Driver/ToolChains/PS4CPU.h7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.cpp7
-rw-r--r--lib/Driver/ToolChains/RISCVToolchain.h7
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp27
-rw-r--r--lib/Driver/ToolChains/Solaris.h7
-rw-r--r--lib/Driver/ToolChains/TCE.cpp7
-rw-r--r--lib/Driver/ToolChains/TCE.h7
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp116
-rw-r--r--lib/Driver/ToolChains/WebAssembly.h17
-rw-r--r--lib/Driver/ToolChains/XCore.cpp7
-rw-r--r--lib/Driver/ToolChains/XCore.h7
-rw-r--r--lib/Driver/Types.cpp7
-rw-r--r--lib/Driver/XRayArgs.cpp7
-rw-r--r--lib/Edit/Commit.cpp7
-rw-r--r--lib/Edit/EditedSource.cpp9
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp10
-rw-r--r--lib/Format/AffectedRangeManager.cpp7
-rw-r--r--lib/Format/AffectedRangeManager.h7
-rw-r--r--lib/Format/BreakableToken.cpp51
-rw-r--r--lib/Format/BreakableToken.h20
-rw-r--r--lib/Format/ContinuationIndenter.cpp120
-rw-r--r--lib/Format/ContinuationIndenter.h11
-rw-r--r--lib/Format/Encoding.h7
-rw-r--r--lib/Format/Format.cpp213
-rw-r--r--lib/Format/FormatInternal.h7
-rw-r--r--lib/Format/FormatToken.cpp7
-rw-r--r--lib/Format/FormatToken.h156
-rw-r--r--lib/Format/FormatTokenLexer.cpp140
-rw-r--r--lib/Format/FormatTokenLexer.h14
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.cpp98
-rw-r--r--lib/Format/NamespaceEndCommentsFixer.h7
-rw-r--r--lib/Format/SortJavaScriptImports.cpp19
-rw-r--r--lib/Format/SortJavaScriptImports.h7
-rw-r--r--lib/Format/TokenAnalyzer.cpp7
-rw-r--r--lib/Format/TokenAnalyzer.h11
-rw-r--r--lib/Format/TokenAnnotator.cpp215
-rw-r--r--lib/Format/TokenAnnotator.h24
-rw-r--r--lib/Format/UnwrappedLineFormatter.cpp90
-rw-r--r--lib/Format/UnwrappedLineFormatter.h13
-rw-r--r--lib/Format/UnwrappedLineParser.cpp123
-rw-r--r--lib/Format/UnwrappedLineParser.h10
-rw-r--r--lib/Format/UsingDeclarationsSorter.cpp10
-rw-r--r--lib/Format/UsingDeclarationsSorter.h7
-rw-r--r--lib/Format/WhitespaceManager.cpp207
-rw-r--r--lib/Format/WhitespaceManager.h12
-rw-r--r--lib/Frontend/ASTConsumers.cpp30
-rw-r--r--lib/Frontend/ASTMerge.cpp21
-rw-r--r--lib/Frontend/ASTUnit.cpp202
-rw-r--r--lib/Frontend/ChainedDiagnosticConsumer.cpp7
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp15
-rw-r--r--lib/Frontend/CompilerInstance.cpp150
-rw-r--r--lib/Frontend/CompilerInvocation.cpp193
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp7
-rw-r--r--lib/Frontend/DependencyFile.cpp285
-rw-r--r--lib/Frontend/DependencyGraph.cpp7
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp7
-rw-r--r--lib/Frontend/FrontendAction.cpp30
-rw-r--r--lib/Frontend/FrontendActions.cpp85
-rw-r--r--lib/Frontend/FrontendOptions.cpp7
-rw-r--r--lib/Frontend/FrontendTiming.cpp9
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp9
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp89
-rw-r--r--lib/Frontend/InitPreprocessor.cpp45
-rw-r--r--lib/Frontend/InterfaceStubFunctionsConsumer.cpp378
-rw-r--r--lib/Frontend/LangStandards.cpp7
-rw-r--r--lib/Frontend/LayoutOverrideSource.cpp7
-rw-r--r--lib/Frontend/LogDiagnosticPrinter.cpp7
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp31
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp13
-rw-r--r--lib/Frontend/PrecompiledPreamble.cpp70
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp45
-rw-r--r--lib/Frontend/Rewrite/FixItRewriter.cpp7
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp15
-rw-r--r--lib/Frontend/Rewrite/HTMLPrint.cpp7
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp9
-rw-r--r--lib/Frontend/Rewrite/RewriteMacros.cpp7
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp73
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp41
-rw-r--r--lib/Frontend/Rewrite/RewriteTest.cpp7
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp9
-rw-r--r--lib/Frontend/SerializedDiagnosticReader.cpp118
-rw-r--r--lib/Frontend/TestModuleFileExtension.cpp24
-rw-r--r--lib/Frontend/TestModuleFileExtension.h9
-rw-r--r--lib/Frontend/TextDiagnostic.cpp35
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp7
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp7
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp443
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp49
-rw-r--r--lib/Headers/__clang_cuda_builtin_vars.h20
-rw-r--r--lib/Headers/__clang_cuda_cmath.h49
-rw-r--r--lib/Headers/__clang_cuda_complex_builtins.h20
-rw-r--r--lib/Headers/__clang_cuda_device_functions.h93
-rw-r--r--lib/Headers/__clang_cuda_intrinsics.h20
-rw-r--r--lib/Headers/__clang_cuda_libdevice_declares.h890
-rw-r--r--lib/Headers/__clang_cuda_math_forward_declares.h70
-rw-r--r--lib/Headers/__clang_cuda_runtime_wrapper.h32
-rw-r--r--lib/Headers/__stddef_max_align_t.h22
-rw-r--r--lib/Headers/__wmmintrin_aes.h20
-rw-r--r--lib/Headers/__wmmintrin_pclmul.h20
-rw-r--r--lib/Headers/adxintrin.h20
-rw-r--r--lib/Headers/altivec.h20
-rw-r--r--lib/Headers/ammintrin.h20
-rw-r--r--lib/Headers/arm64intr.h20
-rw-r--r--lib/Headers/arm_acle.h38
-rw-r--r--lib/Headers/armintr.h20
-rw-r--r--lib/Headers/avx2intrin.h32
-rw-r--r--lib/Headers/avx512bf16intrin.h279
-rw-r--r--lib/Headers/avx512bitalgintrin.h20
-rw-r--r--lib/Headers/avx512bwintrin.h44
-rw-r--r--lib/Headers/avx512cdintrin.h52
-rw-r--r--lib/Headers/avx512dqintrin.h20
-rw-r--r--lib/Headers/avx512erintrin.h20
-rw-r--r--lib/Headers/avx512fintrin.h115
-rw-r--r--lib/Headers/avx512ifmaintrin.h20
-rw-r--r--lib/Headers/avx512ifmavlintrin.h20
-rw-r--r--lib/Headers/avx512pfintrin.h20
-rw-r--r--lib/Headers/avx512vbmi2intrin.h20
-rw-r--r--lib/Headers/avx512vbmiintrin.h20
-rw-r--r--lib/Headers/avx512vbmivlintrin.h20
-rw-r--r--lib/Headers/avx512vlbf16intrin.h474
-rw-r--r--lib/Headers/avx512vlbitalgintrin.h20
-rw-r--r--lib/Headers/avx512vlbwintrin.h36
-rw-r--r--lib/Headers/avx512vlcdintrin.h86
-rw-r--r--lib/Headers/avx512vldqintrin.h52
-rw-r--r--lib/Headers/avx512vlintrin.h77
-rw-r--r--lib/Headers/avx512vlvbmi2intrin.h20
-rw-r--r--lib/Headers/avx512vlvnniintrin.h20
-rw-r--r--lib/Headers/avx512vlvp2intersectintrin.h121
-rw-r--r--lib/Headers/avx512vnniintrin.h20
-rw-r--r--lib/Headers/avx512vp2intersectintrin.h77
-rw-r--r--lib/Headers/avx512vpopcntdqintrin.h20
-rw-r--r--lib/Headers/avx512vpopcntdqvlintrin.h20
-rw-r--r--lib/Headers/avxintrin.h50
-rw-r--r--lib/Headers/bmi2intrin.h20
-rw-r--r--lib/Headers/bmiintrin.h20
-rw-r--r--lib/Headers/cetintrin.h20
-rw-r--r--lib/Headers/cldemoteintrin.h20
-rw-r--r--lib/Headers/clflushoptintrin.h20
-rw-r--r--lib/Headers/clwbintrin.h20
-rw-r--r--lib/Headers/clzerointrin.h20
-rw-r--r--lib/Headers/cpuid.h24
-rw-r--r--lib/Headers/emmintrin.h55
-rw-r--r--lib/Headers/enqcmdintrin.h63
-rw-r--r--lib/Headers/f16cintrin.h26
-rw-r--r--lib/Headers/float.h28
-rw-r--r--lib/Headers/fma4intrin.h20
-rw-r--r--lib/Headers/fmaintrin.h20
-rw-r--r--lib/Headers/fxsrintrin.h20
-rw-r--r--lib/Headers/gfniintrin.h20
-rw-r--r--lib/Headers/htmintrin.h20
-rw-r--r--lib/Headers/htmxlintrin.h20
-rw-r--r--lib/Headers/ia32intrin.h320
-rw-r--r--lib/Headers/immintrin.h62
-rw-r--r--lib/Headers/intrin.h46
-rw-r--r--lib/Headers/inttypes.h25
-rw-r--r--lib/Headers/invpcidintrin.h20
-rw-r--r--lib/Headers/iso646.h22
-rw-r--r--lib/Headers/limits.h22
-rw-r--r--lib/Headers/lwpintrin.h20
-rw-r--r--lib/Headers/lzcntintrin.h20
-rw-r--r--lib/Headers/mm3dnow.h20
-rw-r--r--lib/Headers/mm_malloc.h20
-rw-r--r--lib/Headers/mmintrin.h22
-rw-r--r--lib/Headers/module.modulemap21
-rw-r--r--lib/Headers/movdirintrin.h20
-rw-r--r--lib/Headers/msa.h20
-rw-r--r--lib/Headers/mwaitxintrin.h20
-rw-r--r--lib/Headers/nmmintrin.h20
-rw-r--r--lib/Headers/opencl-c-base.h578
-rw-r--r--lib/Headers/opencl-c.h696
-rw-r--r--lib/Headers/openmp_wrappers/__clang_openmp_math.h35
-rw-r--r--lib/Headers/openmp_wrappers/__clang_openmp_math_declares.h33
-rw-r--r--lib/Headers/openmp_wrappers/cmath16
-rw-r--r--lib/Headers/openmp_wrappers/math.h17
-rw-r--r--lib/Headers/pconfigintrin.h24
-rw-r--r--lib/Headers/pkuintrin.h20
-rw-r--r--lib/Headers/pmmintrin.h20
-rw-r--r--lib/Headers/popcntintrin.h52
-rw-r--r--lib/Headers/ppc_wrappers/emmintrin.h2318
-rw-r--r--lib/Headers/ppc_wrappers/mm_malloc.h44
-rw-r--r--lib/Headers/ppc_wrappers/mmintrin.h1443
-rw-r--r--lib/Headers/ppc_wrappers/xmmintrin.h1838
-rw-r--r--lib/Headers/prfchwintrin.h20
-rw-r--r--lib/Headers/ptwriteintrin.h20
-rw-r--r--lib/Headers/rdseedintrin.h20
-rw-r--r--lib/Headers/rtmintrin.h20
-rw-r--r--lib/Headers/s390intrin.h20
-rw-r--r--lib/Headers/sgxintrin.h24
-rw-r--r--lib/Headers/shaintrin.h20
-rw-r--r--lib/Headers/smmintrin.h20
-rw-r--r--lib/Headers/stdalign.h20
-rw-r--r--lib/Headers/stdarg.h22
-rw-r--r--lib/Headers/stdatomic.h20
-rw-r--r--lib/Headers/stdbool.h22
-rw-r--r--lib/Headers/stddef.h22
-rw-r--r--lib/Headers/stdint.h27
-rw-r--r--lib/Headers/stdnoreturn.h20
-rw-r--r--lib/Headers/tbmintrin.h20
-rw-r--r--lib/Headers/tgmath.h22
-rw-r--r--lib/Headers/tmmintrin.h20
-rw-r--r--lib/Headers/unwind.h24
-rw-r--r--lib/Headers/vadefs.h20
-rw-r--r--lib/Headers/vaesintrin.h20
-rw-r--r--lib/Headers/varargs.h20
-rw-r--r--lib/Headers/vecintrin.h426
-rw-r--r--lib/Headers/vpclmulqdqintrin.h20
-rw-r--r--lib/Headers/waitpkgintrin.h20
-rw-r--r--lib/Headers/wbnoinvdintrin.h20
-rw-r--r--lib/Headers/wmmintrin.h20
-rw-r--r--lib/Headers/x86intrin.h20
-rw-r--r--lib/Headers/xmmintrin.h40
-rw-r--r--lib/Headers/xopintrin.h20
-rw-r--r--lib/Headers/xsavecintrin.h20
-rw-r--r--lib/Headers/xsaveintrin.h39
-rw-r--r--lib/Headers/xsaveoptintrin.h20
-rw-r--r--lib/Headers/xsavesintrin.h20
-rw-r--r--lib/Headers/xtestintrin.h20
-rw-r--r--lib/Index/CodegenNameGenerator.cpp200
-rw-r--r--lib/Index/CommentToXML.cpp14
-rw-r--r--lib/Index/FileIndexRecord.cpp60
-rw-r--r--lib/Index/FileIndexRecord.h57
-rw-r--r--lib/Index/IndexBody.cpp7
-rw-r--r--lib/Index/IndexDecl.cpp35
-rw-r--r--lib/Index/IndexSymbol.cpp49
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp58
-rw-r--r--lib/Index/IndexingAction.cpp7
-rw-r--r--lib/Index/IndexingContext.cpp28
-rw-r--r--lib/Index/IndexingContext.h11
-rw-r--r--lib/Index/SimpleFormatContext.h7
-rw-r--r--lib/Index/USRGeneration.cpp16
-rw-r--r--lib/Lex/DependencyDirectivesSourceMinimizer.cpp763
-rw-r--r--lib/Lex/HeaderMap.cpp7
-rw-r--r--lib/Lex/HeaderSearch.cpp111
-rw-r--r--lib/Lex/Lexer.cpp16
-rw-r--r--lib/Lex/LiteralSupport.cpp19
-rw-r--r--lib/Lex/MacroArgs.cpp18
-rw-r--r--lib/Lex/MacroInfo.cpp7
-rw-r--r--lib/Lex/ModuleMap.cpp23
-rw-r--r--lib/Lex/PPCaching.cpp59
-rw-r--r--lib/Lex/PPCallbacks.cpp7
-rw-r--r--lib/Lex/PPConditionalDirectiveRecord.cpp17
-rw-r--r--lib/Lex/PPDirectives.cpp562
-rw-r--r--lib/Lex/PPExpressions.cpp27
-rw-r--r--lib/Lex/PPLexerChange.cpp34
-rw-r--r--lib/Lex/PPMacroExpansion.cpp112
-rw-r--r--lib/Lex/Pragma.cpp338
-rw-r--r--lib/Lex/PreprocessingRecord.cpp25
-rw-r--r--lib/Lex/Preprocessor.cpp412
-rw-r--r--lib/Lex/PreprocessorLexer.cpp15
-rw-r--r--lib/Lex/ScratchBuffer.cpp7
-rw-r--r--lib/Lex/TokenConcatenation.cpp12
-rw-r--r--lib/Lex/TokenLexer.cpp67
-rw-r--r--lib/Lex/UnicodeCharSets.h7
-rw-r--r--lib/Parse/ParseAST.cpp9
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp24
-rw-r--r--lib/Parse/ParseDecl.cpp258
-rw-r--r--lib/Parse/ParseDeclCXX.cpp178
-rw-r--r--lib/Parse/ParseExpr.cpp182
-rw-r--r--lib/Parse/ParseExprCXX.cpp636
-rw-r--r--lib/Parse/ParseInit.cpp38
-rw-r--r--lib/Parse/ParseObjc.cpp65
-rw-r--r--lib/Parse/ParseOpenMP.cpp528
-rw-r--r--lib/Parse/ParsePragma.cpp225
-rw-r--r--lib/Parse/ParseStmt.cpp149
-rw-r--r--lib/Parse/ParseStmtAsm.cpp87
-rw-r--r--lib/Parse/ParseTemplate.cpp156
-rw-r--r--lib/Parse/ParseTentative.cpp247
-rw-r--r--lib/Parse/Parser.cpp291
-rw-r--r--lib/Rewrite/DeltaTree.cpp7
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp58
-rw-r--r--lib/Rewrite/RewriteRope.cpp7
-rw-r--r--lib/Rewrite/Rewriter.cpp16
-rw-r--r--lib/Rewrite/TokenRewriter.cpp7
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp118
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp7
-rw-r--r--lib/Sema/CoroutineStmtBuilder.h7
-rw-r--r--lib/Sema/DeclSpec.cpp83
-rw-r--r--lib/Sema/DelayedDiagnostic.cpp7
-rw-r--r--lib/Sema/IdentifierResolver.cpp7
-rw-r--r--lib/Sema/JumpDiagnostics.cpp121
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp7
-rw-r--r--lib/Sema/OpenCLBuiltins.td296
-rw-r--r--lib/Sema/ParsedAttr.cpp7
-rw-r--r--lib/Sema/Scope.cpp11
-rw-r--r--lib/Sema/ScopeInfo.cpp63
-rw-r--r--lib/Sema/Sema.cpp433
-rw-r--r--lib/Sema/SemaAccess.cpp10
-rw-r--r--lib/Sema/SemaAttr.cpp22
-rw-r--r--lib/Sema/SemaCUDA.cpp262
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp45
-rw-r--r--lib/Sema/SemaCast.cpp219
-rw-r--r--lib/Sema/SemaChecking.cpp829
-rw-r--r--lib/Sema/SemaCodeComplete.cpp904
-rw-r--r--lib/Sema/SemaConsumer.cpp7
-rw-r--r--lib/Sema/SemaCoroutine.cpp102
-rw-r--r--lib/Sema/SemaDecl.cpp1331
-rw-r--r--lib/Sema/SemaDeclAttr.cpp700
-rw-r--r--lib/Sema/SemaDeclCXX.cpp623
-rw-r--r--lib/Sema/SemaDeclObjC.cpp121
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp42
-rw-r--r--lib/Sema/SemaExpr.cpp2122
-rw-r--r--lib/Sema/SemaExprCXX.cpp368
-rw-r--r--lib/Sema/SemaExprMember.cpp101
-rw-r--r--lib/Sema/SemaExprObjC.cpp92
-rw-r--r--lib/Sema/SemaFixItUtils.cpp7
-rw-r--r--lib/Sema/SemaInit.cpp480
-rw-r--r--lib/Sema/SemaLambda.cpp407
-rw-r--r--lib/Sema/SemaLookup.cpp390
-rw-r--r--lib/Sema/SemaModule.cpp710
-rw-r--r--lib/Sema/SemaObjCProperty.cpp27
-rw-r--r--lib/Sema/SemaOpenMP.cpp2385
-rw-r--r--lib/Sema/SemaOverload.cpp762
-rw-r--r--lib/Sema/SemaPseudoObject.cpp44
-rw-r--r--lib/Sema/SemaStmt.cpp149
-rw-r--r--lib/Sema/SemaStmtAsm.cpp180
-rw-r--r--lib/Sema/SemaStmtAttr.cpp77
-rw-r--r--lib/Sema/SemaTemplate.cpp609
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp54
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp129
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp578
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp69
-rw-r--r--lib/Sema/SemaType.cpp508
-rw-r--r--lib/Sema/TreeTransform.h733
-rw-r--r--lib/Sema/TypeLocBuilder.cpp7
-rw-r--r--lib/Sema/TypeLocBuilder.h7
-rw-r--r--lib/Serialization/ASTCommon.cpp10
-rw-r--r--lib/Serialization/ASTCommon.h23
-rw-r--r--lib/Serialization/ASTReader.cpp1030
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp189
-rw-r--r--lib/Serialization/ASTReaderInternals.h7
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp220
-rw-r--r--lib/Serialization/ASTWriter.cpp212
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp110
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp131
-rw-r--r--lib/Serialization/GeneratePCH.cpp24
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp166
-rw-r--r--lib/Serialization/InMemoryModuleCache.cpp80
-rw-r--r--lib/Serialization/Module.cpp7
-rw-r--r--lib/Serialization/ModuleFileExtension.cpp7
-rw-r--r--lib/Serialization/ModuleManager.cpp60
-rw-r--r--lib/Serialization/MultiOnDiskHashTable.h7
-rw-r--r--lib/Serialization/PCHContainerOperations.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/AllocationState.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp38
-rw-r--r--lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp53
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp237
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp31
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp45
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CastValueChecker.cpp190
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp124
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp70
-rw-r--r--lib/StaticAnalyzer/Checkers/CloneChecker.cpp49
-rw-r--r--lib/StaticAnalyzer/Checkers/ConversionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp34
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp129
-rw-r--r--lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp30
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp28
-rw-r--r--lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp20
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/GCDAntipatternChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/GTestChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp403
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/InnerPointerChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/InterCheckerAPI.h10
-rw-r--r--lib/StaticAnalyzer/Checkers/IteratorChecker.cpp609
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/MIGChecker.cpp295
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h7
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp134
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/MmapWriteExecChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/Move.h30
-rw-r--r--lib/StaticAnalyzer/Checkers/MoveChecker.cpp40
-rw-r--r--lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp34
-rw-r--r--lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/OSObjectCStyleCast.cpp90
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAutoreleaseWriteChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSuperDeallocChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PaddingChecker.cpp32
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerIterationChecker.cpp100
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSortingChecker.cpp113
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp445
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h63
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp186
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h52
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnValueChecker.cpp170
-rw-r--r--lib/StaticAnalyzer/Checkers/RunLoopAutoreleaseLeakChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp18
-rw-r--r--lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp72
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp29
-rw-r--r--lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp21
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/Taint.cpp227
-rw-r--r--lib/StaticAnalyzer/Checkers/Taint.h102
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h37
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp129
-rw-r--r--lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedPointee.cpp7
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp238
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/ValistChecker.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/VforkChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp14
-rw-r--r--lib/StaticAnalyzer/Core/APSIntType.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/AnalysisManager.cpp13
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp119
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/BlockCounter.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp47
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp1365
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp37
-rw-r--r--lib/StaticAnalyzer/Core/Checker.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerContext.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerHelpers.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp104
-rw-r--r--lib/StaticAnalyzer/Core/CommonBugCategories.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp63
-rw-r--r--lib/StaticAnalyzer/Core/DynamicTypeMap.cpp53
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp87
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp282
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp54
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp55
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp78
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/FunctionSummary.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp133
-rw-r--r--lib/StaticAnalyzer/Core/IssueHash.cpp11
-rw-r--r--lib/StaticAnalyzer/Core/LoopUnrolling.cpp9
-rw-r--r--lib/StaticAnalyzer/Core/LoopWidening.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp70
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp136
-rw-r--r--lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h13
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp229
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp86
-rw-r--r--lib/StaticAnalyzer/Core/RangedConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp227
-rw-r--r--lib/StaticAnalyzer/Core/SMTConstraintManager.cpp18
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/SarifDiagnostics.cpp24
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SubEngine.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp17
-rw-r--r--lib/StaticAnalyzer/Core/TaintManager.cpp23
-rw-r--r--lib/StaticAnalyzer/Core/WorkList.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp841
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp94
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp83
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistry.cpp659
-rw-r--r--lib/StaticAnalyzer/Frontend/FrontendActions.cpp7
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelConsumer.cpp7
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.cpp9
-rw-r--r--lib/StaticAnalyzer/Frontend/ModelInjector.h7
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp11
-rw-r--r--lib/Tooling/AllTUsExecution.cpp28
-rw-r--r--lib/Tooling/ArgumentsAdjusters.cpp35
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp11
-rw-r--r--lib/Tooling/CompilationDatabase.cpp7
-rw-r--r--lib/Tooling/Core/Diagnostic.cpp22
-rw-r--r--lib/Tooling/Core/Lookup.cpp92
-rw-r--r--lib/Tooling/Core/Replacement.cpp18
-rw-r--r--lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp149
-rw-r--r--lib/Tooling/Execution.cpp7
-rw-r--r--lib/Tooling/FileMatchTrie.cpp7
-rw-r--r--lib/Tooling/FixIt.cpp14
-rw-r--r--lib/Tooling/GuessTargetAndModeCompilationDatabase.cpp57
-rw-r--r--lib/Tooling/Inclusions/HeaderIncludes.cpp69
-rw-r--r--lib/Tooling/Inclusions/IncludeStyle.cpp7
-rw-r--r--lib/Tooling/InterpolatingCompilationDatabase.cpp28
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp69
-rw-r--r--lib/Tooling/Refactoring.cpp7
-rw-r--r--lib/Tooling/Refactoring/ASTSelection.cpp7
-rw-r--r--lib/Tooling/Refactoring/ASTSelectionRequirements.cpp7
-rw-r--r--lib/Tooling/Refactoring/AtomicChange.cpp7
-rw-r--r--lib/Tooling/Refactoring/Extract/Extract.cpp7
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.cpp7
-rw-r--r--lib/Tooling/Refactoring/Extract/SourceExtraction.h7
-rw-r--r--lib/Tooling/Refactoring/RangeSelector.cpp296
-rw-r--r--lib/Tooling/Refactoring/RefactoringActions.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/RenamingAction.cpp9
-rw-r--r--lib/Tooling/Refactoring/Rename/SymbolOccurrences.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFinder.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFindingAction.cpp7
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp11
-rw-r--r--lib/Tooling/Refactoring/SourceCode.cpp31
-rw-r--r--lib/Tooling/Refactoring/Stencil.cpp175
-rw-r--r--lib/Tooling/Refactoring/Transformer.cpp263
-rw-r--r--lib/Tooling/RefactoringCallbacks.cpp7
-rw-r--r--lib/Tooling/StandaloneExecution.cpp7
-rw-r--r--lib/Tooling/Syntax/BuildTree.cpp273
-rw-r--r--lib/Tooling/Syntax/Nodes.cpp35
-rw-r--r--lib/Tooling/Syntax/Tokens.cpp618
-rw-r--r--lib/Tooling/Syntax/Tree.cpp149
-rw-r--r--lib/Tooling/Tooling.cpp18
947 files changed, 65563 insertions, 29717 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 6da87903a488..568e06f21fba 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -1,9 +1,8 @@
//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -36,10 +35,10 @@ bool CapturedDiagList::clearDiagnostic(ArrayRef<unsigned> IDs,
while (I != List.end()) {
FullSourceLoc diagLoc = I->getLocation();
if ((IDs.empty() || // empty means clear all diagnostics in the range.
- std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
+ llvm::is_contained(IDs, I->getID())) &&
!diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
(diagLoc == range.getEnd() ||
- diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
+ diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
cleared = true;
ListTy::iterator eraseS = I++;
if (eraseS->getLevel() != DiagnosticsEngine::Note)
@@ -65,10 +64,10 @@ bool CapturedDiagList::hasDiagnostic(ArrayRef<unsigned> IDs,
while (I != List.end()) {
FullSourceLoc diagLoc = I->getLocation();
if ((IDs.empty() || // empty means any diagnostic in the range.
- std::find(IDs.begin(), IDs.end(), I->getID()) != IDs.end()) &&
+ llvm::find(IDs, I->getID()) != IDs.end()) &&
!diagLoc.isBeforeInTranslationUnitThan(range.getBegin()) &&
(diagLoc == range.getEnd() ||
- diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
+ diagLoc.isBeforeInTranslationUnitThan(range.getEnd()))) {
return true;
}
@@ -515,7 +514,7 @@ MigrationProcess::MigrationProcess(
IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(),
DiagClient, /*ShouldOwnClient=*/false));
- Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanges=*/true);
+ Remapper.initFromDisk(outputDir, *Diags, /*ignoreIfFilesChanged=*/true);
}
}
diff --git a/lib/ARCMigrate/ARCMTActions.cpp b/lib/ARCMigrate/ARCMTActions.cpp
index 0a5473ab19ec..d72f53806e37 100644
--- a/lib/ARCMigrate/ARCMTActions.cpp
+++ b/lib/ARCMigrate/ARCMTActions.cpp
@@ -1,9 +1,8 @@
//===--- ARCMTActions.cpp - ARC Migrate Tool Frontend Actions ---*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index 225f47119b00..1a4862d09aa6 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -1,9 +1,8 @@
//===--- FileRemapper.cpp - File Remapping Helper -------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index 1a261c1e31aa..47fc09317500 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -1,9 +1,8 @@
//===-- Internals.h - Implementation Details---------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index 6950ce0e12f3..7126a0873ea0 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -1,13 +1,13 @@
//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Transforms.h"
+#include "clang/Analysis/RetainSummaryManager.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
@@ -27,7 +27,6 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/StaticAnalyzer/Core/RetainSummaryManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/Path.h"
@@ -65,9 +64,11 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
ObjCInstanceTypeFamily OIT_Family = OIT_None);
void migrateCFAnnotation(ASTContext &Ctx, const Decl *Decl);
- void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
+ void AddCFAnnotations(ASTContext &Ctx,
+ const RetainSummary *RS,
const FunctionDecl *FuncDecl, bool ResultAnnotated);
- void AddCFAnnotations(ASTContext &Ctx, const CallEffects &CE,
+ void AddCFAnnotations(ASTContext &Ctx,
+ const RetainSummary *RS,
const ObjCMethodDecl *MethodDecl, bool ResultAnnotated);
void AnnotateImplicitBridging(ASTContext &Ctx);
@@ -85,6 +86,8 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
bool InsertFoundation(ASTContext &Ctx, SourceLocation Loc);
+ std::unique_ptr<RetainSummaryManager> Summaries;
+
public:
std::string MigrateDir;
unsigned ASTMigrateActions;
@@ -103,6 +106,14 @@ public:
llvm::SmallVector<const Decl *, 8> CFFunctionIBCandidates;
llvm::StringSet<> WhiteListFilenames;
+ RetainSummaryManager &getSummaryManager(ASTContext &Ctx) {
+ if (!Summaries)
+ Summaries.reset(new RetainSummaryManager(Ctx,
+ /*TrackNSCFObjects=*/true,
+ /*trackOSObjects=*/false));
+ return *Summaries;
+ }
+
ObjCMigrateASTConsumer(StringRef migrateDir,
unsigned astMigrateActions,
FileRemapper &remapper,
@@ -205,7 +216,7 @@ ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
- /*ignoreIfFilesChanges=*/true);
+ /*ignoreIfFilesChanged=*/true);
CompInst = &CI;
CI.getDiagnostics().setIgnoreAllWarnings(true);
return true;
@@ -1453,12 +1464,12 @@ void ObjCMigrateASTConsumer::migrateCFAnnotation(ASTContext &Ctx, const Decl *De
}
void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
- const CallEffects &CE,
+ const RetainSummary *RS,
const FunctionDecl *FuncDecl,
bool ResultAnnotated) {
// Annotate function.
if (!ResultAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
@@ -1478,12 +1489,11 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if (AE.getKind() == DecRef && AE.getObjKind() == ObjKind::CF &&
!pd->hasAttr<CFConsumedAttr>() &&
NSAPIObj->isMacroDefined("CF_CONSUMED")) {
@@ -1507,7 +1517,8 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
if (FuncDecl->hasBody())
return CF_BRIDGING_NONE;
- CallEffects CE = CallEffects::getEffect(FuncDecl);
+ const RetainSummary *RS =
+ getSummaryManager(Ctx).getSummary(AnyCall(FuncDecl));
bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
@@ -1520,7 +1531,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
bool ReturnCFAudited = false;
if (!FuncIsReturnAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
if (Ret.getObjKind() == ObjKind::CF &&
(Ret.isOwned() || Ret.notOwned()))
ReturnCFAudited = true;
@@ -1529,14 +1540,12 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
}
// At this point result type is audited for potential inclusion.
- // Now, how about argument types.
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
bool ArgCFAudited = false;
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
pe = FuncDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if ((AE.getKind() == DecRef /*CFConsumed annotated*/ ||
AE.getKind() == IncRef) && AE.getObjKind() == ObjKind::CF) {
if (AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>())
@@ -1546,7 +1555,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
} else {
QualType AT = pd->getType();
if (!AuditedType(AT)) {
- AddCFAnnotations(Ctx, CE, FuncDecl, FuncIsReturnAnnotated);
+ AddCFAnnotations(Ctx, RS, FuncDecl, FuncIsReturnAnnotated);
return CF_BRIDGING_NONE;
}
}
@@ -1568,12 +1577,12 @@ void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
}
void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
- const CallEffects &CE,
+ const RetainSummary *RS,
const ObjCMethodDecl *MethodDecl,
bool ResultAnnotated) {
// Annotate function.
if (!ResultAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
const char *AnnotationString = nullptr;
if (Ret.getObjKind() == ObjKind::CF) {
if (Ret.isOwned() && NSAPIObj->isMacroDefined("CF_RETURNS_RETAINED"))
@@ -1605,12 +1614,11 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if (AE.getKind() == DecRef
&& AE.getObjKind() == ObjKind::CF
&& !pd->hasAttr<CFConsumedAttr>() &&
@@ -1628,7 +1636,9 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
if (MethodDecl->hasBody() || MethodDecl->isImplicit())
return;
- CallEffects CE = CallEffects::getEffect(MethodDecl);
+ const RetainSummary *RS =
+ getSummaryManager(Ctx).getSummary(AnyCall(MethodDecl));
+
bool MethodIsReturnAnnotated =
(MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
@@ -1636,7 +1646,7 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
- if (CE.getReceiver().getKind() == DecRef &&
+ if (RS->getReceiverEffect().getKind() == DecRef &&
!MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
MethodDecl->getMethodFamily() != OMF_init &&
MethodDecl->getMethodFamily() != OMF_release &&
@@ -1652,27 +1662,25 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
return;
if (!MethodIsReturnAnnotated) {
- RetEffect Ret = CE.getReturnValue();
+ RetEffect Ret = RS->getRetEffect();
if ((Ret.getObjKind() == ObjKind::CF ||
Ret.getObjKind() == ObjKind::ObjC) &&
(Ret.isOwned() || Ret.notOwned())) {
- AddCFAnnotations(Ctx, CE, MethodDecl, false);
+ AddCFAnnotations(Ctx, RS, MethodDecl, false);
return;
} else if (!AuditedType(MethodDecl->getReturnType()))
return;
}
// At this point result type is either annotated or audited.
- // Now, how about argument types.
- ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
for (ObjCMethodDecl::param_const_iterator pi = MethodDecl->param_begin(),
pe = MethodDecl->param_end(); pi != pe; ++pi, ++i) {
const ParmVarDecl *pd = *pi;
- ArgEffect AE = AEArgs[i];
+ ArgEffect AE = RS->getArg(i);
if ((AE.getKind() == DecRef && !pd->hasAttr<CFConsumedAttr>()) ||
AE.getKind() == IncRef || !AuditedType(pd->getType())) {
- AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
+ AddCFAnnotations(Ctx, RS, MethodDecl, MethodIsReturnAnnotated);
return;
}
}
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 9e4cb3f4cd83..6d7fcb053b48 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -1,9 +1,8 @@
//===--- PlistReporter.cpp - ARC Migrate Tool Plist Reporter ----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -121,5 +120,5 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
o << " </array>\n";
// Finish.
- o << "</dict>\n</plist>";
+ o << "</dict>\n</plist>\n";
}
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp
index 6146e07b1d2a..638850dcf9ec 100644
--- a/lib/ARCMigrate/TransAPIUses.cpp
+++ b/lib/ARCMigrate/TransAPIUses.cpp
@@ -1,9 +1,8 @@
//===--- TransAPIUses.cpp - Transformations to ARC mode -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransARCAssign.cpp b/lib/ARCMigrate/TransARCAssign.cpp
index d2b4de4891c3..d1d5b9e014b1 100644
--- a/lib/ARCMigrate/TransARCAssign.cpp
+++ b/lib/ARCMigrate/TransARCAssign.cpp
@@ -1,9 +1,8 @@
//===--- TransARCAssign.cpp - Transformations to ARC mode -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
index 9d20774a89a6..393adcd85a3f 100644
--- a/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -1,9 +1,8 @@
//===--- TransAutoreleasePool.cpp - Transformations to ARC mode -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 85bdabb50461..1e4db33135b6 100644
--- a/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -1,9 +1,8 @@
//===--- TransBlockObjCVariable.cpp - Transformations to ARC mode ---------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index 0327b0def1e6..5d0cfb8a8b9c 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -1,9 +1,8 @@
-//===--- TransEmptyStatements.cpp - Transformations to ARC mode -----------===//
+//===-- TransEmptyStatementsAndDealloc.cpp - Transformations to ARC mode --===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -43,9 +42,8 @@ static bool isEmptyARCMTMacroStatement(NullStmt *S,
return false;
SourceManager &SM = Ctx.getSourceManager();
- std::vector<SourceLocation>::iterator
- I = std::upper_bound(MacroLocs.begin(), MacroLocs.end(), SemiLoc,
- BeforeThanCompare<SourceLocation>(SM));
+ std::vector<SourceLocation>::iterator I = llvm::upper_bound(
+ MacroLocs, SemiLoc, BeforeThanCompare<SourceLocation>(SM));
--I;
SourceLocation
AfterMacroLoc = I->getLocWithOffset(getARCMTMacroName().size());
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index 7697d3f048e6..5e3162197ed1 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -1,9 +1,8 @@
//===--- TransGCAttrs.cpp - Transformations to ARC mode --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -69,6 +68,9 @@ public:
if (handleAttr(Attr, D))
break;
TL = Attr.getModifiedLoc();
+ } else if (MacroQualifiedTypeLoc MDTL =
+ TL.getAs<MacroQualifiedTypeLoc>()) {
+ TL = MDTL.getInnerLoc();
} else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) {
TL = Arr.getElementLoc();
} else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) {
@@ -267,7 +269,7 @@ static void checkAllAtProps(MigrationContext &MigrateCtx,
StringRef toAttr = "strong";
if (hasWeak) {
if (canApplyWeak(MigrateCtx.Pass.Ctx, IndProps.front()->getType(),
- /*AllowOnUnkwownClass=*/true))
+ /*AllowOnUnknownClass=*/true))
toAttr = "weak";
else
toAttr = "unsafe_unretained";
diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp
index eff142ba3922..43233e2d0b45 100644
--- a/lib/ARCMigrate/TransGCCalls.cpp
+++ b/lib/ARCMigrate/TransGCCalls.cpp
@@ -1,9 +1,8 @@
//===--- TransGCCalls.cpp - Transformations to ARC mode -------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index 912f77aeb789..0675fb0baeb8 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -1,9 +1,8 @@
//===--- TransProperties.cpp - Transformations to ARC mode ----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp
index bfc542e7497c..9e9e9cb7a96d 100644
--- a/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/lib/ARCMigrate/TransProtectedScope.cpp
@@ -1,9 +1,8 @@
//===--- TransProtectedScope.cpp - Transformations to ARC mode ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index d199bb936547..b76fc65574dd 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -1,9 +1,8 @@
//===--- TransRetainReleaseDealloc.cpp - Transformations to ARC mode ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -270,8 +269,8 @@ private:
if (prevChildS != childE) {
prevStmt = *prevChildS;
- if (prevStmt)
- prevStmt = prevStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(prevStmt))
+ prevStmt = E->IgnoreImplicit();
}
if (currChildS == childE)
@@ -281,8 +280,8 @@ private:
return std::make_pair(prevStmt, nextStmt);
nextStmt = *currChildS;
- if (nextStmt)
- nextStmt = nextStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(nextStmt))
+ nextStmt = E->IgnoreImplicit();
return std::make_pair(prevStmt, nextStmt);
}
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 9d46d8c5fcae..e767ad5346c3 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -1,9 +1,8 @@
//===--- TransUnbridgedCasts.cpp - Transformations to ARC mode ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
index 70370ecc4e90..bac8dfac9b41 100644
--- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -1,9 +1,8 @@
//===--- TransUnusedInitDelegate.cpp - Transformations to ARC mode --------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Transformations:
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 220102ec49ce..d28bd378acc1 100644
--- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -1,9 +1,8 @@
//===--- TransZeroOutPropsInDealloc.cpp - Transformations to ARC mode -----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index d1768bc56cfc..2c48e479dce8 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -1,9 +1,8 @@
-//===--- ARCMT.cpp - Migration to ARC mode --------------------------------===//
+//===-- TransformActions.cpp - Migration to ARC mode ----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -314,7 +313,9 @@ void TransformActionsImpl::removeStmt(Stmt *S) {
assert(IsInTransaction && "Actions only allowed during a transaction");
ActionData data;
data.Kind = Act_RemoveStmt;
- data.S = S->IgnoreImplicit(); // important for uniquing
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit(); // important for uniquing
+ data.S = S;
CachedActions.push_back(data);
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 8bd2b407aee9..59b80a917e56 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -1,9 +1,8 @@
//===--- Transforms.cpp - Transformations to ARC mode ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -287,10 +286,11 @@ private:
void mark(Stmt *S) {
if (!S) return;
- while (LabelStmt *Label = dyn_cast<LabelStmt>(S))
+ while (auto *Label = dyn_cast<LabelStmt>(S))
S = Label->getSubStmt();
- S = S->IgnoreImplicit();
- if (Expr *E = dyn_cast<Expr>(S))
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit();
+ if (auto *E = dyn_cast<Expr>(S))
Removables.insert(E);
}
};
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
index bafe9fc52a27..e087136f0e2c 100644
--- a/lib/ARCMigrate/Transforms.h
+++ b/lib/ARCMigrate/Transforms.h
@@ -1,9 +1,8 @@
//===-- Transforms.h - Transformations to ARC mode --------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index c05b160b8e3d..1993bba9bd1a 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -1,9 +1,8 @@
//===--- APValue.cpp - Union class for APFloat/APSInt/Complex -------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,6 +20,61 @@
#include "llvm/Support/raw_ostream.h"
using namespace clang;
+/// The identity of a type_info object depends on the canonical unqualified
+/// type only.
+TypeInfoLValue::TypeInfoLValue(const Type *T)
+ : T(T->getCanonicalTypeUnqualified().getTypePtr()) {}
+
+void TypeInfoLValue::print(llvm::raw_ostream &Out,
+ const PrintingPolicy &Policy) const {
+ Out << "typeid(";
+ QualType(getType(), 0).print(Out, Policy);
+ Out << ")";
+}
+
+static_assert(
+ 1 << llvm::PointerLikeTypeTraits<TypeInfoLValue>::NumLowBitsAvailable <=
+ alignof(Type),
+ "Type is insufficiently aligned");
+
+APValue::LValueBase::LValueBase(const ValueDecl *P, unsigned I, unsigned V)
+ : Ptr(P), Local{I, V} {}
+APValue::LValueBase::LValueBase(const Expr *P, unsigned I, unsigned V)
+ : Ptr(P), Local{I, V} {}
+
+APValue::LValueBase APValue::LValueBase::getTypeInfo(TypeInfoLValue LV,
+ QualType TypeInfo) {
+ LValueBase Base;
+ Base.Ptr = LV;
+ Base.TypeInfoType = TypeInfo.getAsOpaquePtr();
+ return Base;
+}
+
+unsigned APValue::LValueBase::getCallIndex() const {
+ return is<TypeInfoLValue>() ? 0 : Local.CallIndex;
+}
+
+unsigned APValue::LValueBase::getVersion() const {
+ return is<TypeInfoLValue>() ? 0 : Local.Version;
+}
+
+QualType APValue::LValueBase::getTypeInfoType() const {
+ assert(is<TypeInfoLValue>() && "not a type_info lvalue");
+ return QualType::getFromOpaquePtr(TypeInfoType);
+}
+
+namespace clang {
+bool operator==(const APValue::LValueBase &LHS,
+ const APValue::LValueBase &RHS) {
+ if (LHS.Ptr != RHS.Ptr)
+ return false;
+ if (LHS.is<TypeInfoLValue>())
+ return true;
+ return LHS.Local.CallIndex == RHS.Local.CallIndex &&
+ LHS.Local.Version == RHS.Local.Version;
+}
+}
+
namespace {
struct LVBase {
APValue::LValueBase Base;
@@ -46,26 +100,27 @@ APValue::LValueBase::operator bool () const {
clang::APValue::LValueBase
llvm::DenseMapInfo<clang::APValue::LValueBase>::getEmptyKey() {
return clang::APValue::LValueBase(
- DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getEmptyKey(),
- DenseMapInfo<unsigned>::getEmptyKey(),
- DenseMapInfo<unsigned>::getEmptyKey());
+ DenseMapInfo<const ValueDecl*>::getEmptyKey());
}
clang::APValue::LValueBase
llvm::DenseMapInfo<clang::APValue::LValueBase>::getTombstoneKey() {
return clang::APValue::LValueBase(
- DenseMapInfo<clang::APValue::LValueBase::PtrTy>::getTombstoneKey(),
- DenseMapInfo<unsigned>::getTombstoneKey(),
- DenseMapInfo<unsigned>::getTombstoneKey());
+ DenseMapInfo<const ValueDecl*>::getTombstoneKey());
+}
+
+namespace clang {
+llvm::hash_code hash_value(const APValue::LValueBase &Base) {
+ if (Base.is<TypeInfoLValue>())
+ return llvm::hash_value(Base.getOpaqueValue());
+ return llvm::hash_combine(Base.getOpaqueValue(), Base.getCallIndex(),
+ Base.getVersion());
+}
}
unsigned llvm::DenseMapInfo<clang::APValue::LValueBase>::getHashValue(
const clang::APValue::LValueBase &Base) {
- llvm::FoldingSetNodeID ID;
- ID.AddPointer(Base.getOpaqueValue());
- ID.AddInteger(Base.getCallIndex());
- ID.AddInteger(Base.getVersion());
- return ID.ComputeHash();
+ return hash_value(Base);
}
bool llvm::DenseMapInfo<clang::APValue::LValueBase>::isEqual(
@@ -164,9 +219,11 @@ APValue::UnionData::~UnionData () {
delete Value;
}
-APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
+APValue::APValue(const APValue &RHS) : Kind(None) {
switch (RHS.getKind()) {
- case Uninitialized:
+ case None:
+ case Indeterminate:
+ Kind = RHS.getKind();
break;
case Int:
MakeInt();
@@ -176,6 +233,11 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
MakeFloat();
setFloat(RHS.getFloat());
break;
+ case FixedPoint: {
+ APFixedPoint FXCopy = RHS.getFixedPoint();
+ MakeFixedPoint(std::move(FXCopy));
+ break;
+ }
case Vector:
MakeVector();
setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
@@ -233,6 +295,8 @@ void APValue::DestroyDataAndMakeUninit() {
((APSInt*)(char*)Data.buffer)->~APSInt();
else if (Kind == Float)
((APFloat*)(char*)Data.buffer)->~APFloat();
+ else if (Kind == FixedPoint)
+ ((APFixedPoint *)(char *)Data.buffer)->~APFixedPoint();
else if (Kind == Vector)
((Vec*)(char*)Data.buffer)->~Vec();
else if (Kind == ComplexInt)
@@ -251,12 +315,13 @@ void APValue::DestroyDataAndMakeUninit() {
((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
else if (Kind == AddrLabelDiff)
((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
- Kind = Uninitialized;
+ Kind = None;
}
bool APValue::needsCleanup() const {
switch (getKind()) {
- case Uninitialized:
+ case None:
+ case Indeterminate:
case AddrLabelDiff:
return false;
case Struct:
@@ -268,6 +333,8 @@ bool APValue::needsCleanup() const {
return getInt().needsCleanup();
case Float:
return getFloat().needsCleanup();
+ case FixedPoint:
+ return getFixedPoint().getValue().needsCleanup();
case ComplexFloat:
assert(getComplexFloatImag().needsCleanup() ==
getComplexFloatReal().needsCleanup() &&
@@ -312,8 +379,11 @@ static double GetApproxValue(const llvm::APFloat &F) {
void APValue::dump(raw_ostream &OS) const {
switch (getKind()) {
- case Uninitialized:
- OS << "Uninitialized";
+ case None:
+ OS << "None";
+ return;
+ case Indeterminate:
+ OS << "Indeterminate";
return;
case Int:
OS << "Int: " << getInt();
@@ -321,6 +391,9 @@ void APValue::dump(raw_ostream &OS) const {
case Float:
OS << "Float: " << GetApproxValue(getFloat());
return;
+ case FixedPoint:
+ OS << "FixedPoint : " << getFixedPoint();
+ return;
case Vector:
OS << "Vector: ";
getVectorElt(0).dump(OS);
@@ -383,9 +456,13 @@ void APValue::dump(raw_ostream &OS) const {
llvm_unreachable("Unknown APValue kind!");
}
-void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
+void APValue::printPretty(raw_ostream &Out, const ASTContext &Ctx,
+ QualType Ty) const {
switch (getKind()) {
- case APValue::Uninitialized:
+ case APValue::None:
+ Out << "<out of lifetime>";
+ return;
+ case APValue::Indeterminate:
Out << "<uninitialized>";
return;
case APValue::Int:
@@ -397,6 +474,9 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
case APValue::Float:
Out << GetApproxValue(getFloat());
return;
+ case APValue::FixedPoint:
+ Out << getFixedPoint();
+ return;
case APValue::Vector: {
Out << '{';
QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
@@ -453,7 +533,9 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
- else {
+ else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
+ TI.print(Out, Ctx.getPrintingPolicy());
+ } else {
assert(Base.get<const Expr *>() != nullptr &&
"Expecting non-null Expr");
Base.get<const Expr*>()->printPretty(Out, nullptr,
@@ -478,6 +560,9 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
Out << *VD;
ElemTy = VD->getType();
+ } else if (TypeInfoLValue TI = Base.dyn_cast<TypeInfoLValue>()) {
+ TI.print(Out, Ctx.getPrintingPolicy());
+ ElemTy = Base.getTypeInfoType();
} else {
const Expr *E = Base.get<const Expr*>();
assert(E != nullptr && "Expecting non-null Expr");
@@ -491,8 +576,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
if (ElemTy->getAs<RecordType>()) {
// The lvalue refers to a class type, so the next path entry is a base
// or member.
- const Decl *BaseOrMember =
- BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
+ const Decl *BaseOrMember = Path[I].getAsBaseOrMember().getPointer();
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
CastToBase = RD;
ElemTy = Ctx.getRecordType(RD);
@@ -506,7 +590,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
}
} else {
// The lvalue must refer to an array.
- Out << '[' << Path[I].ArrayIndex << ']';
+ Out << '[' << Path[I].getAsArrayIndex() << ']';
ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
}
}
@@ -592,7 +676,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
llvm_unreachable("Unknown APValue kind!");
}
-std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
+std::string APValue::getAsString(const ASTContext &Ctx, QualType Ty) const {
std::string Result;
llvm::raw_string_ostream Out(Result);
printPretty(Out, Ctx, Ty);
@@ -600,6 +684,26 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
return Result;
}
+bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy,
+ const ASTContext &Ctx) const {
+ if (isInt()) {
+ Result = getInt();
+ return true;
+ }
+
+ if (isLValue() && isNullPointer()) {
+ Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy);
+ return true;
+ }
+
+ if (isLValue() && !getLValueBase()) {
+ Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy);
+ return true;
+ }
+
+ return false;
+}
+
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
return ((const LV*)(const void*)Data.buffer)->Base;
@@ -687,21 +791,21 @@ ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
}
void APValue::MakeLValue() {
- assert(isUninit() && "Bad state change");
+ assert(isAbsent() && "Bad state change");
static_assert(sizeof(LV) <= DataSize, "LV too big");
new ((void*)(char*)Data.buffer) LV();
Kind = LValue;
}
void APValue::MakeArray(unsigned InitElts, unsigned Size) {
- assert(isUninit() && "Bad state change");
+ assert(isAbsent() && "Bad state change");
new ((void*)(char*)Data.buffer) Arr(InitElts, Size);
Kind = Array;
}
void APValue::MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path) {
- assert(isUninit() && "Bad state change");
+ assert(isAbsent() && "Bad state change");
MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
Kind = MemberPointer;
MPD->MemberAndIsDerivedMember.setPointer(Member);
diff --git a/lib/AST/ASTConsumer.cpp b/lib/AST/ASTConsumer.cpp
index 55033b238c66..6bba8f1f80a9 100644
--- a/lib/AST/ASTConsumer.cpp
+++ b/lib/AST/ASTConsumer.cpp
@@ -1,9 +1,8 @@
//===--- ASTConsumer.cpp - Abstract interface for reading ASTs --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 21b6f36e9aa7..0d69eb90abaf 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1,9 +1,8 @@
//===- ASTContext.cpp - Context to hold long-lived AST nodes --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -95,38 +94,18 @@
using namespace clang;
-unsigned ASTContext::NumImplicitDefaultConstructors;
-unsigned ASTContext::NumImplicitDefaultConstructorsDeclared;
-unsigned ASTContext::NumImplicitCopyConstructors;
-unsigned ASTContext::NumImplicitCopyConstructorsDeclared;
-unsigned ASTContext::NumImplicitMoveConstructors;
-unsigned ASTContext::NumImplicitMoveConstructorsDeclared;
-unsigned ASTContext::NumImplicitCopyAssignmentOperators;
-unsigned ASTContext::NumImplicitCopyAssignmentOperatorsDeclared;
-unsigned ASTContext::NumImplicitMoveAssignmentOperators;
-unsigned ASTContext::NumImplicitMoveAssignmentOperatorsDeclared;
-unsigned ASTContext::NumImplicitDestructors;
-unsigned ASTContext::NumImplicitDestructorsDeclared;
-
enum FloatingRank {
Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
- if (!CommentsLoaded && ExternalSource) {
- ExternalSource->ReadComments();
-
-#ifndef NDEBUG
- ArrayRef<RawComment *> RawComments = Comments.getComments();
- assert(std::is_sorted(RawComments.begin(), RawComments.end(),
- BeforeThanCompare<RawComment>(SourceMgr)));
-#endif
-
- CommentsLoaded = true;
- }
-
assert(D);
+ // If we already tried to load comments but there are none,
+ // we won't find anything.
+ if (CommentsLoaded && Comments.getComments().empty())
+ return nullptr;
+
// User can not attach documentation to implicit declarations.
if (D->isImplicit())
return nullptr;
@@ -176,12 +155,6 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
isa<TemplateTemplateParmDecl>(D))
return nullptr;
- ArrayRef<RawComment *> RawComments = Comments.getComments();
-
- // If there are no comments anywhere, we won't find anything.
- if (RawComments.empty())
- return nullptr;
-
// Find declaration location.
// For Objective-C declarations we generally don't expect to have multiple
// declarators, thus use declaration starting location as the "declaration
@@ -220,6 +193,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
return nullptr;
+ if (!CommentsLoaded && ExternalSource) {
+ ExternalSource->ReadComments();
+
+#ifndef NDEBUG
+ ArrayRef<RawComment *> RawComments = Comments.getComments();
+ assert(std::is_sorted(RawComments.begin(), RawComments.end(),
+ BeforeThanCompare<RawComment>(SourceMgr)));
+#endif
+
+ CommentsLoaded = true;
+ }
+
+ ArrayRef<RawComment *> RawComments = Comments.getComments();
+ // If there are no comments anywhere, we won't find anything.
+ if (RawComments.empty())
+ return nullptr;
+
// Find the comment that occurs just after this declaration.
ArrayRef<RawComment *>::iterator Comment;
{
@@ -238,12 +228,11 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (Found) {
Comment = MaybeBeforeDecl + 1;
- assert(Comment == std::lower_bound(RawComments.begin(), RawComments.end(),
- &CommentAtDeclLoc, Compare));
+ assert(Comment ==
+ llvm::lower_bound(RawComments, &CommentAtDeclLoc, Compare));
} else {
// Slow path.
- Comment = std::lower_bound(RawComments.begin(), RawComments.end(),
- &CommentAtDeclLoc, Compare);
+ Comment = llvm::lower_bound(RawComments, &CommentAtDeclLoc, Compare);
}
}
@@ -265,6 +254,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
SourceMgr.getLineNumber(DeclLocDecomp.first, DeclLocDecomp.second)
== SourceMgr.getLineNumber(CommentBeginDecomp.first,
CommentBeginDecomp.second)) {
+ (**Comment).setAttached();
return *Comment;
}
}
@@ -306,6 +296,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
if (Text.find_first_of(";{}#@") != StringRef::npos)
return nullptr;
+ (**Comment).setAttached();
return *Comment;
}
@@ -835,6 +826,9 @@ ASTContext::~ASTContext() {
for (const auto &Value : ModuleInitializers)
Value.second->~PerModuleInitializers();
+
+ for (APValue *Value : APValueCleanups)
+ Value->~APValue();
}
class ASTContext::ParentMap {
@@ -913,7 +907,7 @@ void ASTContext::setTraversalScope(const std::vector<Decl *> &TopLevelDecls) {
Parents.reset();
}
-void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
+void ASTContext::AddDeallocation(void (*Callback)(void *), void *Data) const {
Deallocations.push_back({Callback, Data});
}
@@ -1391,24 +1385,6 @@ ASTContext::setTemplateOrSpecializationInfo(VarDecl *Inst,
TemplateOrInstantiation[Inst] = TSI;
}
-FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
- const FunctionDecl *FD){
- assert(FD && "Specialization is 0");
- llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
- = ClassScopeSpecializationPattern.find(FD);
- if (Pos == ClassScopeSpecializationPattern.end())
- return nullptr;
-
- return Pos->second;
-}
-
-void ASTContext::setClassScopeSpecializationPattern(FunctionDecl *FD,
- FunctionDecl *Pattern) {
- assert(FD && "Specialization is 0");
- assert(Pattern && "Class scope specialization pattern is 0");
- ClassScopeSpecializationPattern[FD] = Pattern;
-}
-
NamedDecl *
ASTContext::getInstantiatedFromUsingDecl(NamedDecl *UUD) {
auto Pos = InstantiatedFromUsingDecl.find(UUD);
@@ -1548,8 +1524,14 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
return Target->getHalfFormat();
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
- case BuiltinType::LongDouble: return Target->getLongDoubleFormat();
- case BuiltinType::Float128: return Target->getFloat128Format();
+ case BuiltinType::LongDouble:
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
+ return AuxTarget->getLongDoubleFormat();
+ return Target->getLongDoubleFormat();
+ case BuiltinType::Float128:
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice)
+ return AuxTarget->getFloat128Format();
+ return Target->getFloat128Format();
}
}
@@ -1610,8 +1592,10 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
if (BaseT.getQualifiers().hasUnaligned())
Align = Target->getCharWidth();
if (const auto *VD = dyn_cast<VarDecl>(D)) {
- if (VD->hasGlobalStorage() && !ForAlignof)
- Align = std::max(Align, getTargetInfo().getMinGlobalAlign());
+ if (VD->hasGlobalStorage() && !ForAlignof) {
+ uint64_t TypeSize = getTypeSize(T.getTypePtr());
+ Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
+ }
}
}
@@ -1916,8 +1900,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
case BuiltinType::Float16:
case BuiltinType::Half:
- Width = Target->getHalfWidth();
- Align = Target->getHalfAlign();
+ if (Target->hasFloat16Type() || !getLangOpts().OpenMP ||
+ !getLangOpts().OpenMPIsDevice) {
+ Width = Target->getHalfWidth();
+ Align = Target->getHalfAlign();
+ } else {
+ assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ Width = AuxTarget->getHalfWidth();
+ Align = AuxTarget->getHalfAlign();
+ }
break;
case BuiltinType::Float:
Width = Target->getFloatWidth();
@@ -1928,12 +1920,27 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Align = Target->getDoubleAlign();
break;
case BuiltinType::LongDouble:
- Width = Target->getLongDoubleWidth();
- Align = Target->getLongDoubleAlign();
+ if (getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ (Target->getLongDoubleWidth() != AuxTarget->getLongDoubleWidth() ||
+ Target->getLongDoubleAlign() != AuxTarget->getLongDoubleAlign())) {
+ Width = AuxTarget->getLongDoubleWidth();
+ Align = AuxTarget->getLongDoubleAlign();
+ } else {
+ Width = Target->getLongDoubleWidth();
+ Align = Target->getLongDoubleAlign();
+ }
break;
case BuiltinType::Float128:
- Width = Target->getFloat128Width();
- Align = Target->getFloat128Align();
+ if (Target->hasFloat128Type() || !getLangOpts().OpenMP ||
+ !getLangOpts().OpenMPIsDevice) {
+ Width = Target->getFloat128Width();
+ Align = Target->getFloat128Align();
+ } else {
+ assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
+ "Expected OpenMP device compilation.");
+ Width = AuxTarget->getFloat128Width();
+ Align = AuxTarget->getFloat128Align();
+ }
break;
case BuiltinType::NullPtr:
Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
@@ -2057,6 +2064,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Paren:
return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
+ case Type::MacroQualified:
+ return getTypeInfo(
+ cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());
+
case Type::ObjCTypeParam:
return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
@@ -2134,7 +2145,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
} else {
- UnadjustedAlign = getTypeAlign(T);
+ UnadjustedAlign = getTypeAlign(T->getUnqualifiedDesugaredType());
}
MemoizedUnadjustedAlign[T] = UnadjustedAlign;
@@ -2233,7 +2244,8 @@ unsigned ASTContext::getTargetDefaultAlignForAttributeAligned() const {
/// getAlignOfGlobalVar - Return the alignment in bits that should be given
/// to a global variable of the specified type.
unsigned ASTContext::getAlignOfGlobalVar(QualType T) const {
- return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign());
+ uint64_t TypeSize = getTypeSize(T.getTypePtr());
+ return std::max(getTypeAlign(T), getTargetInfo().getMinGlobalAlign(TypeSize));
}
/// getAlignOfGlobalVarInChars - Return the alignment in characters that
@@ -2574,7 +2586,7 @@ ASTContext::getBlockVarCopyInit(const VarDecl*VD) const {
return {nullptr, false};
}
-/// Set the copy inialization expression of a block var decl.
+/// Set the copy initialization expression of a block var decl.
void ASTContext::setBlockVarCopyInit(const VarDecl*VD, Expr *CopyExpr,
bool CanThrow) {
assert(VD && CopyExpr && "Passed null params");
@@ -2763,6 +2775,12 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(
return getParenType(
getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
+ // Might be wrapped in a macro qualified type.
+ if (const auto *MQT = dyn_cast<MacroQualifiedType>(Orig))
+ return getMacroQualifiedType(
+ getFunctionTypeWithExceptionSpec(MQT->getUnderlyingType(), ESI),
+ MQT->getMacroIdentifier());
+
// Might have a calling-convention attribute.
if (const auto *AT = dyn_cast<AttributedType>(Orig))
return getAttributedType(
@@ -2772,7 +2790,7 @@ QualType ASTContext::getFunctionTypeWithExceptionSpec(
// Anything else must be a function type. Rebuild it with the new exception
// specification.
- const auto *Proto = cast<FunctionProtoType>(Orig);
+ const auto *Proto = Orig->getAs<FunctionProtoType>();
return getFunctionType(
Proto->getReturnType(), Proto->getParamTypes(),
Proto->getExtProtoInfo().withExceptionSpec(ESI));
@@ -3739,7 +3757,10 @@ QualType ASTContext::getFunctionTypeInternal(
break;
}
- case EST_DynamicNone: case EST_BasicNoexcept: case EST_NoexceptTrue:
+ case EST_DynamicNone:
+ case EST_BasicNoexcept:
+ case EST_NoexceptTrue:
+ case EST_NoThrow:
CanonicalEPI.ExceptionSpec.Type = EST_BasicNoexcept;
break;
@@ -3938,7 +3959,7 @@ QualType ASTContext::getAttributedType(attr::Kind attrKind,
QualType canon = getCanonicalType(equivalentType);
type = new (*this, TypeAlignment)
- AttributedType(canon, attrKind, modifiedType, equivalentType);
+ AttributedType(canon, attrKind, modifiedType, equivalentType);
Types.push_back(type);
AttributedTypes.InsertNode(type, insertPos);
@@ -4219,6 +4240,19 @@ ASTContext::getParenType(QualType InnerType) const {
return QualType(T, 0);
}
+QualType
+ASTContext::getMacroQualifiedType(QualType UnderlyingTy,
+ const IdentifierInfo *MacroII) const {
+ QualType Canon = UnderlyingTy;
+ if (!Canon.isCanonical())
+ Canon = getCanonicalType(UnderlyingTy);
+
+ auto *newType = new (*this, TypeAlignment)
+ MacroQualifiedType(UnderlyingTy, Canon, MacroII);
+ Types.push_back(newType);
+ return QualType(newType, 0);
+}
+
QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
@@ -4356,7 +4390,13 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
llvm::FoldingSetNodeID ID;
PackExpansionType::Profile(ID, Pattern, NumExpansions);
- assert(Pattern->containsUnexpandedParameterPack() &&
+ // A deduced type can deduce to a pack, eg
+ // auto ...x = some_pack;
+ // That declaration isn't (yet) valid, but is created as part of building an
+ // init-capture pack:
+ // [...x = some_pack] {}
+ assert((Pattern->containsUnexpandedParameterPack() ||
+ Pattern->getContainedDeducedType()) &&
"Pack expansions must expand one or more parameter packs");
void *InsertPos = nullptr;
PackExpansionType *T
@@ -4856,19 +4896,20 @@ QualType ASTContext::getUnaryTransformType(QualType BaseType,
/// deduced to the given type, or to the canonical undeduced 'auto' type, or the
/// canonical deduced-but-dependent 'auto' type.
QualType ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
- bool IsDependent) const {
+ bool IsDependent, bool IsPack) const {
+ assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack");
if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto && !IsDependent)
return getAutoDeductType();
// Look in the folding set for an existing type.
void *InsertPos = nullptr;
llvm::FoldingSetNodeID ID;
- AutoType::Profile(ID, DeducedType, Keyword, IsDependent);
+ AutoType::Profile(ID, DeducedType, Keyword, IsDependent, IsPack);
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
auto *AT = new (*this, TypeAlignment)
- AutoType(DeducedType, Keyword, IsDependent);
+ AutoType(DeducedType, Keyword, IsDependent, IsPack);
Types.push_back(AT);
if (InsertPos)
AutoTypes.InsertNode(AT, InsertPos);
@@ -4930,7 +4971,7 @@ QualType ASTContext::getAutoDeductType() const {
if (AutoDeductTy.isNull())
AutoDeductTy = QualType(
new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto,
- /*dependent*/false),
+ /*dependent*/false, /*pack*/false),
0);
return AutoDeductTy;
}
@@ -5218,6 +5259,11 @@ ASTContext::getNameForTemplate(TemplateName Name,
return DeclarationNameInfo((*Storage->begin())->getDeclName(), NameLoc);
}
+ case TemplateName::AssumedTemplate: {
+ AssumedTemplateStorage *Storage = Name.getAsAssumedTemplateName();
+ return DeclarationNameInfo(Storage->getDeclName(), NameLoc);
+ }
+
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
DeclarationName DName;
@@ -5265,7 +5311,8 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name) const {
}
case TemplateName::OverloadedTemplate:
- llvm_unreachable("cannot canonicalize overloaded template");
+ case TemplateName::AssumedTemplate:
+ llvm_unreachable("cannot canonicalize unresolved template");
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
@@ -5609,6 +5656,12 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) const {
return -1;
}
+int ASTContext::getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const {
+ if (&getFloatTypeSemantics(LHS) == &getFloatTypeSemantics(RHS))
+ return 0;
+ return getFloatingTypeOrder(LHS, RHS);
+}
+
/// getIntegerRank - Return an integer conversion rank (C99 6.3.1.1p1). This
/// routine will assert if passed a built-in type that isn't an integer or enum,
/// or if it is not canonicalized.
@@ -6283,12 +6336,13 @@ void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
// Encode type qualifer, 'in', 'inout', etc. for the parameter.
getObjCEncodingForTypeQualifier(QT, S);
// Encode parameter type.
- getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
- true /*OutermostType*/,
- false /*EncodingProperty*/,
- false /*StructField*/,
- Extended /*EncodeBlockParameters*/,
- Extended /*EncodeClassNames*/);
+ ObjCEncOptions Options = ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType();
+ if (Extended)
+ Options.setEncodeBlockParameters().setEncodeClassNames();
+ getObjCEncodingForTypeImpl(T, S, Options, /*Field=*/nullptr);
}
/// getObjCEncodingForMethodDecl - Return the encoded type for this method
@@ -6480,9 +6534,12 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
// directly pointed to, and expanding embedded structures. Note that
// these rules are sufficient to prevent recursive encoding of the
// same type.
- getObjCEncodingForTypeImpl(T, S, true, true, Field,
- true /* outermost type */, false, false,
- false, false, false, NotEncodedT);
+ getObjCEncodingForTypeImpl(T, S,
+ ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType(),
+ Field, NotEncodedT);
}
void ASTContext::getObjCEncodingForPropertyType(QualType T,
@@ -6490,9 +6547,13 @@ void ASTContext::getObjCEncodingForPropertyType(QualType T,
// Encode result type.
// GCC has some special rules regarding encoding of properties which
// closely resembles encoding of ivars.
- getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
- true /* outermost type */,
- true /* encoding property */);
+ getObjCEncodingForTypeImpl(T, S,
+ ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()
+ .setIsOutermostType()
+ .setEncodingProperty(),
+ /*Field=*/nullptr);
}
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
@@ -6639,16 +6700,9 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
}
// FIXME: Use SmallString for accumulating string.
-void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
- bool ExpandPointedToStructures,
- bool ExpandStructures,
+void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
+ const ObjCEncOptions Options,
const FieldDecl *FD,
- bool OutermostType,
- bool EncodingProperty,
- bool StructField,
- bool EncodeBlockParameters,
- bool EncodeClassNames,
- bool EncodePointerToObjCTypedef,
QualType *NotEncodedT) const {
CanQualType CT = getCanonicalType(T);
switch (CT->getTypeClass()) {
@@ -6665,14 +6719,16 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Complex: {
const auto *CT = T->castAs<ComplexType>();
S += 'j';
- getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr);
+ getObjCEncodingForTypeImpl(CT->getElementType(), S, ObjCEncOptions(),
+ /*Field=*/nullptr);
return;
}
case Type::Atomic: {
const auto *AT = T->castAs<AtomicType>();
S += 'A';
- getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr);
+ getObjCEncodingForTypeImpl(AT->getValueType(), S, ObjCEncOptions(),
+ /*Field=*/nullptr);
return;
}
@@ -6698,11 +6754,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// the pointer itself gets ignored, _unless_ we are looking at a typedef!
// Also, do not emit the 'r' for anything but the outermost type!
if (isa<TypedefType>(T.getTypePtr())) {
- if (OutermostType && T.isConstQualified()) {
+ if (Options.IsOutermostType() && T.isConstQualified()) {
isReadOnly = true;
S += 'r';
}
- } else if (OutermostType) {
+ } else if (Options.IsOutermostType()) {
QualType P = PointeeTy;
while (P->getAs<PointerType>())
P = P->getAs<PointerType>()->getPointeeType();
@@ -6742,9 +6798,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '^';
getLegacyIntegralTypeEncoding(PointeeTy);
- getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
- nullptr, false, false, false, false, false, false,
- NotEncodedT);
+ ObjCEncOptions NewOptions;
+ if (Options.ExpandPointedToStructures())
+ NewOptions.setExpandStructures();
+ getObjCEncodingForTypeImpl(PointeeTy, S, NewOptions,
+ /*Field=*/nullptr, NotEncodedT);
return;
}
@@ -6753,12 +6811,13 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::VariableArray: {
const auto *AT = cast<ArrayType>(CT);
- if (isa<IncompleteArrayType>(AT) && !StructField) {
+ if (isa<IncompleteArrayType>(AT) && !Options.IsStructField()) {
// Incomplete arrays are encoded as a pointer to the array element.
S += '^';
- getObjCEncodingForTypeImpl(AT->getElementType(), S,
- false, ExpandStructures, FD);
+ getObjCEncodingForTypeImpl(
+ AT->getElementType(), S,
+ Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD);
} else {
S += '[';
@@ -6771,10 +6830,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '0';
}
- getObjCEncodingForTypeImpl(AT->getElementType(), S,
- false, ExpandStructures, FD,
- false, false, false, false, false, false,
- NotEncodedT);
+ getObjCEncodingForTypeImpl(
+ AT->getElementType(), S,
+ Options.keepingOnly(ObjCEncOptions().setExpandStructures()), FD,
+ NotEncodedT);
S += ']';
}
return;
@@ -6800,7 +6859,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
} else {
S += '?';
}
- if (ExpandStructures) {
+ if (Options.ExpandStructures()) {
S += '=';
if (!RDecl->isUnion()) {
getObjCEncodingForStructureImpl(RDecl, S, FD, true, NotEncodedT);
@@ -6814,16 +6873,16 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Special case bit-fields.
if (Field->isBitField()) {
- getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
+ getObjCEncodingForTypeImpl(Field->getType(), S,
+ ObjCEncOptions().setExpandStructures(),
Field);
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
- getObjCEncodingForTypeImpl(qt, S, false, true,
- FD, /*OutermostType*/false,
- /*EncodingProperty*/false,
- /*StructField*/true,
- false, false, false, NotEncodedT);
+ getObjCEncodingForTypeImpl(
+ qt, S,
+ ObjCEncOptions().setExpandStructures().setIsStructField(), FD,
+ NotEncodedT);
}
}
}
@@ -6835,26 +6894,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::BlockPointer: {
const auto *BT = T->castAs<BlockPointerType>();
S += "@?"; // Unlike a pointer-to-function, which is "^?".
- if (EncodeBlockParameters) {
+ if (Options.EncodeBlockParameters()) {
const auto *FT = BT->getPointeeType()->castAs<FunctionType>();
S += '<';
// Block return type
- getObjCEncodingForTypeImpl(
- FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
- FD, false /* OutermostType */, EncodingProperty,
- false /* StructField */, EncodeBlockParameters, EncodeClassNames, false,
- NotEncodedT);
+ getObjCEncodingForTypeImpl(FT->getReturnType(), S,
+ Options.forComponentType(), FD, NotEncodedT);
// Block self
S += "@?";
// Block parameters
if (const auto *FPT = dyn_cast<FunctionProtoType>(FT)) {
for (const auto &I : FPT->param_types())
- getObjCEncodingForTypeImpl(
- I, S, ExpandPointedToStructures, ExpandStructures, FD,
- false /* OutermostType */, EncodingProperty,
- false /* StructField */, EncodeBlockParameters, EncodeClassNames,
- false, NotEncodedT);
+ getObjCEncodingForTypeImpl(I, S, Options.forComponentType(), FD,
+ NotEncodedT);
}
S += '>';
}
@@ -6882,18 +6935,19 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
ObjCInterfaceDecl *OI = T->castAs<ObjCObjectType>()->getInterface();
S += '{';
S += OI->getObjCRuntimeNameAsString();
- if (ExpandStructures) {
+ if (Options.ExpandStructures()) {
S += '=';
SmallVector<const ObjCIvarDecl*, 32> Ivars;
DeepCollectObjCIvars(OI, true, Ivars);
for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
const FieldDecl *Field = Ivars[i];
if (Field->isBitField())
- getObjCEncodingForTypeImpl(Field->getType(), S, false, true, Field);
+ getObjCEncodingForTypeImpl(Field->getType(), S,
+ ObjCEncOptions().setExpandStructures(),
+ Field);
else
- getObjCEncodingForTypeImpl(Field->getType(), S, false, true, FD,
- false, false, false, false, false,
- EncodePointerToObjCTypedef,
+ getObjCEncodingForTypeImpl(Field->getType(), S,
+ ObjCEncOptions().setExpandStructures(), FD,
NotEncodedT);
}
}
@@ -6910,17 +6964,20 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
// FIXME: Consider if we need to output qualifiers for 'Class<p>'.
- // Since this is a binary compatibility issue, need to consult with runtime
- // folks. Fortunately, this is a *very* obscure construct.
+ // Since this is a binary compatibility issue, need to consult with
+ // runtime folks. Fortunately, this is a *very* obscure construct.
S += '#';
return;
}
if (OPT->isObjCQualifiedIdType()) {
- getObjCEncodingForTypeImpl(getObjCIdType(), S,
- ExpandPointedToStructures,
- ExpandStructures, FD);
- if (FD || EncodingProperty || EncodeClassNames) {
+ getObjCEncodingForTypeImpl(
+ getObjCIdType(), S,
+ Options.keepingOnly(ObjCEncOptions()
+ .setExpandPointedToStructures()
+ .setExpandStructures()),
+ FD);
+ if (FD || Options.EncodingProperty() || Options.EncodeClassNames()) {
// Note that we do extended encoding of protocol qualifer list
// Only when doing ivar or property encoding.
S += '"';
@@ -6934,39 +6991,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
return;
}
- QualType PointeeTy = OPT->getPointeeType();
- if (!EncodingProperty &&
- isa<TypedefType>(PointeeTy.getTypePtr()) &&
- !EncodePointerToObjCTypedef) {
- // Another historical/compatibility reason.
- // We encode the underlying type which comes out as
- // {...};
- S += '^';
- if (FD && OPT->getInterfaceDecl()) {
- // Prevent recursive encoding of fields in some rare cases.
- ObjCInterfaceDecl *OI = OPT->getInterfaceDecl();
- SmallVector<const ObjCIvarDecl*, 32> Ivars;
- DeepCollectObjCIvars(OI, true, Ivars);
- for (unsigned i = 0, e = Ivars.size(); i != e; ++i) {
- if (Ivars[i] == FD) {
- S += '{';
- S += OI->getObjCRuntimeNameAsString();
- S += '}';
- return;
- }
- }
- }
- getObjCEncodingForTypeImpl(PointeeTy, S,
- false, ExpandPointedToStructures,
- nullptr,
- false, false, false, false, false,
- /*EncodePointerToObjCTypedef*/true);
- return;
- }
-
S += '@';
if (OPT->getInterfaceDecl() &&
- (FD || EncodingProperty || EncodeClassNames)) {
+ (FD || Options.EncodingProperty() || Options.EncodeClassNames())) {
S += '"';
S += OPT->getInterfaceDecl()->getObjCRuntimeNameAsString();
for (const auto *I : OPT->quals()) {
@@ -6980,7 +7007,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
// gcc just blithely ignores member pointers.
- // FIXME: we shoul do better than that. 'M' is available.
+ // FIXME: we should do better than that. 'M' is available.
case Type::MemberPointer:
// This matches gcc's encoding, even though technically it is insufficient.
//FIXME. We should do a better job than gcc.
@@ -7142,11 +7169,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
} else {
QualType qt = field->getType();
getLegacyIntegralTypeEncoding(qt);
- getObjCEncodingForTypeImpl(qt, S, false, true, FD,
- /*OutermostType*/false,
- /*EncodingProperty*/false,
- /*StructField*/true,
- false, false, false, NotEncodedT);
+ getObjCEncodingForTypeImpl(
+ qt, S, ObjCEncOptions().setExpandStructures().setIsStructField(),
+ FD, NotEncodedT);
#ifndef NDEBUG
CurOffs += getTypeSize(field->getType());
#endif
@@ -7606,6 +7631,13 @@ ASTContext::getOverloadedTemplateName(UnresolvedSetIterator Begin,
return TemplateName(OT);
}
+/// Retrieve a template name representing an unqualified-id that has been
+/// assumed to name a template for ADL purposes.
+TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const {
+ auto *OT = new (*this) AssumedTemplateStorage(Name);
+ return TemplateName(OT);
+}
+
/// Retrieve the template name that represents a qualified
/// template name such as \c std::vector.
TemplateName
@@ -8581,7 +8613,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lproto->isVariadic() != rproto->isVariadic())
return {};
- if (lproto->getTypeQuals() != rproto->getTypeQuals())
+ if (lproto->getMethodQuals() != rproto->getMethodQuals())
return {};
SmallVector<FunctionProtoType::ExtParameterInfo, 4> newParamInfos;
@@ -9246,7 +9278,7 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
// Read the prefixed modifiers first.
bool Done = false;
#ifndef NDEBUG
- bool IsSpecialLong = false;
+ bool IsSpecial = false;
#endif
while (!Done) {
switch (*Str++) {
@@ -9265,26 +9297,26 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
Unsigned = true;
break;
case 'L':
- assert(!IsSpecialLong && "Can't use 'L' with 'W' or 'N' modifiers");
+ assert(!IsSpecial && "Can't use 'L' with 'W', 'N', 'Z' or 'O' modifiers");
assert(HowLong <= 2 && "Can't have LLLL modifier");
++HowLong;
break;
case 'N':
// 'N' behaves like 'L' for all non LP64 targets and 'int' otherwise.
- assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
+ assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");
assert(HowLong == 0 && "Can't use both 'L' and 'N' modifiers!");
#ifndef NDEBUG
- IsSpecialLong = true;
+ IsSpecial = true;
#endif
if (Context.getTargetInfo().getLongWidth() == 32)
++HowLong;
break;
case 'W':
// This modifier represents int64 type.
- assert(!IsSpecialLong && "Can't use two 'N' or 'W' modifiers!");
+ assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");
assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");
#ifndef NDEBUG
- IsSpecialLong = true;
+ IsSpecial = true;
#endif
switch (Context.getTargetInfo().getInt64Type()) {
default:
@@ -9297,6 +9329,38 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
break;
}
break;
+ case 'Z':
+ // This modifier represents int32 type.
+ assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");
+ assert(HowLong == 0 && "Can't use both 'L' and 'Z' modifiers!");
+ #ifndef NDEBUG
+ IsSpecial = true;
+ #endif
+ switch (Context.getTargetInfo().getIntTypeByWidth(32, true)) {
+ default:
+ llvm_unreachable("Unexpected integer type");
+ case TargetInfo::SignedInt:
+ HowLong = 0;
+ break;
+ case TargetInfo::SignedLong:
+ HowLong = 1;
+ break;
+ case TargetInfo::SignedLongLong:
+ HowLong = 2;
+ break;
+ }
+ break;
+ case 'O':
+ assert(!IsSpecial && "Can't use two 'N', 'W', 'Z' or 'O' modifiers!");
+ assert(HowLong == 0 && "Can't use both 'L' and 'O' modifiers!");
+ #ifndef NDEBUG
+ IsSpecial = true;
+ #endif
+ if (Context.getLangOpts().OpenCL)
+ HowLong = 1;
+ else
+ HowLong = 2;
+ break;
}
}
@@ -9518,6 +9582,10 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs) const {
const char *TypeStr = BuiltinInfo.getTypeString(Id);
+ if (TypeStr[0] == '\0') {
+ Error = GE_Missing_type;
+ return {};
+ }
SmallVector<QualType, 8> ArgTypes;
@@ -9553,10 +9621,12 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
assert((TypeStr[0] != '.' || TypeStr[1] == 0) &&
"'.' should only occur at end of builtin type list!");
- FunctionType::ExtInfo EI(CC_C);
+ bool Variadic = (TypeStr[0] == '.');
+
+ FunctionType::ExtInfo EI(getDefaultCallingConvention(
+ Variadic, /*IsCXXMethod=*/false, /*IsBuiltin=*/true));
if (BuiltinInfo.isNoReturn(Id)) EI = EI.withNoReturn(true);
- bool Variadic = (TypeStr[0] == '.');
// We really shouldn't be making a no-proto type here.
if (ArgTypes.empty() && Variadic && !getLangOpts().CPlusPlus)
@@ -9784,12 +9854,12 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
return false;
} else if (isa<PragmaCommentDecl>(D))
return true;
- else if (isa<OMPThreadPrivateDecl>(D))
- return true;
else if (isa<PragmaDetectMismatchDecl>(D))
return true;
else if (isa<OMPThreadPrivateDecl>(D))
return !D->getDeclContext()->isDependentContext();
+ else if (isa<OMPAllocateDecl>(D))
+ return !D->getDeclContext()->isDependentContext();
else if (isa<OMPDeclareReductionDecl>(D))
return !D->getDeclContext()->isDependentContext();
else if (isa<ImportDecl>(D))
@@ -9931,34 +10001,39 @@ void ASTContext::forEachMultiversionedFunctionVersion(
}
CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
- bool IsCXXMethod) const {
+ bool IsCXXMethod,
+ bool IsBuiltin) const {
// Pass through to the C++ ABI object
if (IsCXXMethod)
return ABI->getDefaultMethodCallConv(IsVariadic);
- switch (LangOpts.getDefaultCallingConv()) {
- case LangOptions::DCC_None:
- break;
- case LangOptions::DCC_CDecl:
- return CC_C;
- case LangOptions::DCC_FastCall:
- if (getTargetInfo().hasFeature("sse2") && !IsVariadic)
- return CC_X86FastCall;
- break;
- case LangOptions::DCC_StdCall:
- if (!IsVariadic)
- return CC_X86StdCall;
- break;
- case LangOptions::DCC_VectorCall:
- // __vectorcall cannot be applied to variadic functions.
- if (!IsVariadic)
- return CC_X86VectorCall;
- break;
- case LangOptions::DCC_RegCall:
- // __regcall cannot be applied to variadic functions.
- if (!IsVariadic)
- return CC_X86RegCall;
- break;
+ // Builtins ignore user-specified default calling convention and remain the
+ // Target's default calling convention.
+ if (!IsBuiltin) {
+ switch (LangOpts.getDefaultCallingConv()) {
+ case LangOptions::DCC_None:
+ break;
+ case LangOptions::DCC_CDecl:
+ return CC_C;
+ case LangOptions::DCC_FastCall:
+ if (getTargetInfo().hasFeature("sse2") && !IsVariadic)
+ return CC_X86FastCall;
+ break;
+ case LangOptions::DCC_StdCall:
+ if (!IsVariadic)
+ return CC_X86StdCall;
+ break;
+ case LangOptions::DCC_VectorCall:
+ // __vectorcall cannot be applied to variadic functions.
+ if (!IsVariadic)
+ return CC_X86VectorCall;
+ break;
+ case LangOptions::DCC_RegCall:
+ // __regcall cannot be applied to variadic functions.
+ if (!IsVariadic)
+ return CC_X86RegCall;
+ break;
+ }
}
return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown);
}
@@ -9978,8 +10053,10 @@ VTableContextBase *ASTContext::getVTableContext() {
return VTContext.get();
}
-MangleContext *ASTContext::createMangleContext() {
- switch (Target->getCXXABI().getKind()) {
+MangleContext *ASTContext::createMangleContext(const TargetInfo *T) {
+ if (!T)
+ T = Target;
+ switch (T->getCXXABI().getKind()) {
case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
case TargetCXXABI::GenericARM:
@@ -10010,8 +10087,7 @@ size_t ASTContext::getSideTableAllocatedMemory() const {
llvm::capacity_in_bytes(InstantiatedFromUnnamedFieldDecl) +
llvm::capacity_in_bytes(OverriddenMethods) +
llvm::capacity_in_bytes(Types) +
- llvm::capacity_in_bytes(VariableArrayTypes) +
- llvm::capacity_in_bytes(ClassScopeSpecializationPattern);
+ llvm::capacity_in_bytes(VariableArrayTypes);
}
/// getIntTypeForBitwidth -
@@ -10140,6 +10216,31 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
return MaterializedTemporaryValues.lookup(E);
}
+QualType ASTContext::getStringLiteralArrayType(QualType EltTy,
+ unsigned Length) const {
+ // A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
+ if (getLangOpts().CPlusPlus || getLangOpts().ConstStrings)
+ EltTy = EltTy.withConst();
+
+ EltTy = adjustStringLiteralBaseType(EltTy);
+
+ // Get an array type for the string, according to C99 6.4.5. This includes
+ // the null terminator character.
+ return getConstantArrayType(EltTy, llvm::APInt(32, Length + 1),
+ ArrayType::Normal, /*IndexTypeQuals*/ 0);
+}
+
+StringLiteral *
+ASTContext::getPredefinedStringLiteralFromCache(StringRef Key) const {
+ StringLiteral *&Result = StringLiteralCache[Key];
+ if (!Result)
+ Result = StringLiteral::Create(
+ *this, Key, StringLiteral::Ascii,
+ /*Pascal*/ false, getStringLiteralArrayType(CharTy, Key.size()),
+ SourceLocation());
+ return Result;
+}
+
bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
const llvm::Triple &T = getTargetInfo().getTriple();
if (!T.isOSDarwin())
@@ -10485,7 +10586,13 @@ unsigned char ASTContext::getFixedPointIBits(QualType Ty) const {
}
FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const {
- assert(Ty->isFixedPointType());
+ assert((Ty->isFixedPointType() || Ty->isIntegerType()) &&
+ "Can only get the fixed point semantics for a "
+ "fixed point or integer type.");
+ if (Ty->isIntegerType())
+ return FixedPointSemantics::GetIntegerSemantics(getIntWidth(Ty),
+ Ty->isSignedIntegerType());
+
bool isSigned = Ty->isSignedFixedPointType();
return FixedPointSemantics(
static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned,
@@ -10502,3 +10609,38 @@ APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {
assert(Ty->isFixedPointType());
return APFixedPoint::getMin(getFixedPointSemantics(Ty));
}
+
+QualType ASTContext::getCorrespondingSignedFixedPointType(QualType Ty) const {
+ assert(Ty->isUnsignedFixedPointType() &&
+ "Expected unsigned fixed point type");
+ const auto *BTy = Ty->getAs<BuiltinType>();
+
+ switch (BTy->getKind()) {
+ case BuiltinType::UShortAccum:
+ return ShortAccumTy;
+ case BuiltinType::UAccum:
+ return AccumTy;
+ case BuiltinType::ULongAccum:
+ return LongAccumTy;
+ case BuiltinType::SatUShortAccum:
+ return SatShortAccumTy;
+ case BuiltinType::SatUAccum:
+ return SatAccumTy;
+ case BuiltinType::SatULongAccum:
+ return SatLongAccumTy;
+ case BuiltinType::UShortFract:
+ return ShortFractTy;
+ case BuiltinType::UFract:
+ return FractTy;
+ case BuiltinType::ULongFract:
+ return LongFractTy;
+ case BuiltinType::SatUShortFract:
+ return SatShortFractTy;
+ case BuiltinType::SatUFract:
+ return SatFractTy;
+ case BuiltinType::SatULongFract:
+ return SatLongFractTy;
+ default:
+ llvm_unreachable("Unexpected unsigned fixed point type");
+ }
+}
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index dd0585558572..15df86585294 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -1,9 +1,8 @@
//===--- ASTDiagnostic.cpp - Diagnostic Printing Hooks for AST Nodes ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -42,6 +41,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = PT->desugar();
continue;
}
+ // ... or a macro defined type ...
+ if (const MacroQualifiedType *MDT = dyn_cast<MacroQualifiedType>(Ty)) {
+ QT = MDT->desugar();
+ continue;
+ }
// ...or a substituted template type parameter ...
if (const SubstTemplateTypeParmType *ST =
dyn_cast<SubstTemplateTypeParmType>(Ty)) {
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index b52ec21943e6..22196a1a2600 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1,9 +1,8 @@
//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,21 +11,10 @@
//
//===----------------------------------------------------------------------===//
+#include "clang/AST/ASTDumper.h"
#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"
-#include "clang/AST/DeclObjC.h"
-#include "clang/AST/DeclOpenMP.h"
-#include "clang/AST/DeclVisitor.h"
-#include "clang/AST/LocInfoType.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/AST/TemplateArgumentVisitor.h"
-#include "clang/AST/TextNodeDumper.h"
-#include "clang/AST/TypeVisitor.h"
+#include "clang/AST/JSONNodeDumper.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
@@ -34,345 +22,8 @@
using namespace clang;
using namespace clang::comments;
-//===----------------------------------------------------------------------===//
-// ASTDumper Visitor
-//===----------------------------------------------------------------------===//
-
-namespace {
-
- class ASTDumper
- : public ConstDeclVisitor<ASTDumper>,
- public ConstStmtVisitor<ASTDumper>,
- public ConstCommentVisitor<ASTDumper, void, const FullComment *>,
- public TypeVisitor<ASTDumper>,
- public ConstAttrVisitor<ASTDumper>,
- public ConstTemplateArgumentVisitor<ASTDumper> {
-
- TextNodeDumper NodeDumper;
-
- raw_ostream &OS;
-
- /// The policy to use for printing; can be defaulted.
- PrintingPolicy PrintPolicy;
-
- /// Indicates whether we should trigger deserialization of nodes that had
- /// not already been loaded.
- bool Deserialize = false;
-
- const bool ShowColors;
-
- /// Dump a child of the current node.
- template<typename Fn> void dumpChild(Fn DoDumpChild) {
- NodeDumper.AddChild(DoDumpChild);
- }
- template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) {
- NodeDumper.AddChild(Label, DoDumpChild);
- }
-
- public:
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM)
- : ASTDumper(OS, Traits, SM,
- SM && SM->getDiagnostics().getShowColors()) {}
-
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors)
- : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
- ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
- const SourceManager *SM, bool ShowColors,
- const PrintingPolicy &PrintPolicy)
- : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
- PrintPolicy(PrintPolicy), ShowColors(ShowColors) {}
-
- void setDeserialize(bool D) { Deserialize = D; }
-
- void dumpDecl(const Decl *D);
- void dumpStmt(const Stmt *S, StringRef Label = {});
-
- // Utilities
- void dumpTypeAsChild(QualType T);
- void dumpTypeAsChild(const Type *T);
- void dumpDeclContext(const DeclContext *DC);
- void dumpLookups(const DeclContext *DC, bool DumpDecls);
- void dumpAttr(const Attr *A);
-
- // C++ Utilities
- void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
- void dumpTemplateParameters(const TemplateParameterList *TPL);
- void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
- void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
- const Decl *From = nullptr,
- const char *Label = nullptr);
- void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
- void dumpTemplateArgument(const TemplateArgument &A,
- SourceRange R = SourceRange(),
- const Decl *From = nullptr,
- const char *Label = nullptr);
- template <typename SpecializationDecl>
- void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
- bool DumpExplicitInst,
- bool DumpRefOnly);
- template <typename TemplateDecl>
- void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
-
- // Objective-C utilities.
- void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams);
-
- // Types
- void VisitComplexType(const ComplexType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitLocInfoType(const LocInfoType *T) {
- dumpTypeAsChild(T->getTypeSourceInfo()->getType());
- }
- void VisitPointerType(const PointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitBlockPointerType(const BlockPointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitReferenceType(const ReferenceType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitMemberPointerType(const MemberPointerType *T) {
- dumpTypeAsChild(T->getClass());
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitArrayType(const ArrayType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitVariableArrayType(const VariableArrayType *T) {
- VisitArrayType(T);
- dumpStmt(T->getSizeExpr());
- }
- void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
- dumpTypeAsChild(T->getElementType());
- dumpStmt(T->getSizeExpr());
- }
- void VisitDependentSizedExtVectorType(
- const DependentSizedExtVectorType *T) {
- dumpTypeAsChild(T->getElementType());
- dumpStmt(T->getSizeExpr());
- }
- void VisitVectorType(const VectorType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitFunctionType(const FunctionType *T) {
- dumpTypeAsChild(T->getReturnType());
- }
- void VisitFunctionProtoType(const FunctionProtoType *T) {
- VisitFunctionType(T);
- for (QualType PT : T->getParamTypes())
- dumpTypeAsChild(PT);
- if (T->getExtProtoInfo().Variadic)
- dumpChild([=] { OS << "..."; });
- }
- void VisitTypeOfExprType(const TypeOfExprType *T) {
- dumpStmt(T->getUnderlyingExpr());
- }
- void VisitDecltypeType(const DecltypeType *T) {
- dumpStmt(T->getUnderlyingExpr());
- }
- void VisitUnaryTransformType(const UnaryTransformType *T) {
- dumpTypeAsChild(T->getBaseType());
- }
- void VisitAttributedType(const AttributedType *T) {
- // FIXME: AttrKind
- dumpTypeAsChild(T->getModifiedType());
- }
- void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
- dumpTypeAsChild(T->getReplacedParameter());
- }
- void VisitSubstTemplateTypeParmPackType(
- const SubstTemplateTypeParmPackType *T) {
- dumpTypeAsChild(T->getReplacedParameter());
- dumpTemplateArgument(T->getArgumentPack());
- }
- void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
- for (auto &Arg : *T)
- dumpTemplateArgument(Arg);
- if (T->isTypeAlias())
- dumpTypeAsChild(T->getAliasedType());
- }
- void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
- dumpTypeAsChild(T->getPointeeType());
- }
- void VisitAtomicType(const AtomicType *T) {
- dumpTypeAsChild(T->getValueType());
- }
- void VisitPipeType(const PipeType *T) {
- dumpTypeAsChild(T->getElementType());
- }
- void VisitAdjustedType(const AdjustedType *T) {
- dumpTypeAsChild(T->getOriginalType());
- }
- void VisitPackExpansionType(const PackExpansionType *T) {
- if (!T->isSugared())
- dumpTypeAsChild(T->getPattern());
- }
- // FIXME: ElaboratedType, DependentNameType,
- // DependentTemplateSpecializationType, ObjCObjectType
-
- // Decls
- void VisitLabelDecl(const LabelDecl *D);
- void VisitTypedefDecl(const TypedefDecl *D);
- void VisitEnumDecl(const EnumDecl *D);
- void VisitRecordDecl(const RecordDecl *D);
- void VisitEnumConstantDecl(const EnumConstantDecl *D);
- void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
- void VisitFunctionDecl(const FunctionDecl *D);
- void VisitFieldDecl(const FieldDecl *D);
- void VisitVarDecl(const VarDecl *D);
- void VisitDecompositionDecl(const DecompositionDecl *D);
- void VisitBindingDecl(const BindingDecl *D);
- void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
- void VisitImportDecl(const ImportDecl *D);
- void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
- void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
- void VisitCapturedDecl(const CapturedDecl *D);
-
- // OpenMP decls
- void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
- void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
- void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
- void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
-
- // C++ Decls
- void VisitNamespaceDecl(const NamespaceDecl *D);
- void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
- void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
- void VisitTypeAliasDecl(const TypeAliasDecl *D);
- void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
- void VisitCXXRecordDecl(const CXXRecordDecl *D);
- void VisitStaticAssertDecl(const StaticAssertDecl *D);
- void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
- void VisitClassTemplateDecl(const ClassTemplateDecl *D);
- void VisitClassTemplateSpecializationDecl(
- const ClassTemplateSpecializationDecl *D);
- void VisitClassTemplatePartialSpecializationDecl(
- const ClassTemplatePartialSpecializationDecl *D);
- void VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D);
- void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
- void VisitVarTemplateDecl(const VarTemplateDecl *D);
- void VisitVarTemplateSpecializationDecl(
- const VarTemplateSpecializationDecl *D);
- void VisitVarTemplatePartialSpecializationDecl(
- const VarTemplatePartialSpecializationDecl *D);
- void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
- void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
- void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
- void VisitUsingDecl(const UsingDecl *D);
- void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
- void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
- void VisitUsingShadowDecl(const UsingShadowDecl *D);
- void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
- void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
- void VisitAccessSpecDecl(const AccessSpecDecl *D);
- void VisitFriendDecl(const FriendDecl *D);
-
- // ObjC Decls
- void VisitObjCIvarDecl(const ObjCIvarDecl *D);
- void VisitObjCMethodDecl(const ObjCMethodDecl *D);
- void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
- void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
- void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
- void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
- void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
- void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
- void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
- void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
- void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
- void Visit(const BlockDecl::Capture &C);
- void VisitBlockDecl(const BlockDecl *D);
-
- // Stmts.
- void VisitDeclStmt(const DeclStmt *Node);
- void VisitAttributedStmt(const AttributedStmt *Node);
- void VisitCXXCatchStmt(const CXXCatchStmt *Node);
- void VisitCapturedStmt(const CapturedStmt *Node);
-
- // OpenMP
- void Visit(const OMPClause *C);
- void VisitOMPExecutableDirective(const OMPExecutableDirective *Node);
-
- // Exprs
- void VisitInitListExpr(const InitListExpr *ILE);
- void VisitBlockExpr(const BlockExpr *Node);
- void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
- void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
-
- // C++
- void VisitLambdaExpr(const LambdaExpr *Node) {
- dumpDecl(Node->getLambdaClass());
- }
- void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
-
- // ObjC
- void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
-
- // Comments.
- void dumpComment(const Comment *C, const FullComment *FC);
-
- void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
- dumpStmt(TA.getAsExpr());
- }
- void VisitPackTemplateArgument(const TemplateArgument &TA) {
- for (const auto &TArg : TA.pack_elements())
- dumpTemplateArgument(TArg);
- }
-
-// Implements Visit methods for Attrs.
-#include "clang/AST/AttrNodeTraverse.inc"
- };
-}
-
-//===----------------------------------------------------------------------===//
-// Utilities
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpTypeAsChild(QualType T) {
- SplitQualType SQT = T.split();
- if (!SQT.Quals.hasQualifiers())
- return dumpTypeAsChild(SQT.Ty);
-
- dumpChild([=] {
- NodeDumper.Visit(T);
- dumpTypeAsChild(T.split().Ty);
- });
-}
-
-void ASTDumper::dumpTypeAsChild(const Type *T) {
- dumpChild([=] {
- NodeDumper.Visit(T);
- if (!T)
- return;
- TypeVisitor<ASTDumper>::Visit(T);
-
- QualType SingleStepDesugar =
- T->getLocallyUnqualifiedSingleStepDesugaredType();
- if (SingleStepDesugar != QualType(T, 0))
- dumpTypeAsChild(SingleStepDesugar);
- });
-}
-
-void ASTDumper::dumpDeclContext(const DeclContext *DC) {
- if (!DC)
- return;
-
- for (auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
- dumpDecl(D);
-
- if (DC->hasExternalLexicalStorage()) {
- dumpChild([=] {
- ColorScope Color(OS, ShowColors, UndeserializedColor);
- OS << "<undeserialized declarations>";
- });
- }
-}
-
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
OS << "StoredDeclsMap ";
NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
@@ -384,14 +35,14 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
- auto Range = Deserialize
+ auto Range = getDeserialize()
? Primary->lookups()
: Primary->noload_lookups(/*PreserveInternalState=*/true);
for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
DeclarationName Name = I.getLookupName();
DeclContextLookupResult R = *I;
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
OS << "DeclarationName ";
{
ColorScope Color(OS, ShowColors, DeclNameColor);
@@ -400,7 +51,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
RI != RE; ++RI) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
NodeDumper.dumpBareDeclRef(*RI);
if ((*RI)->isHidden())
@@ -412,7 +63,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
if (Decl *Prev = D->getPreviousDecl())
DumpWithPrev(Prev);
- dumpDecl(D);
+ Visit(D);
};
DumpWithPrev(*RI);
}
@@ -422,7 +73,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
}
if (HasUndeserializedLookups) {
- dumpChild([=] {
+ NodeDumper.AddChild([=] {
ColorScope Color(OS, ShowColors, UndeserializedColor);
OS << "<undeserialized lookups>";
});
@@ -430,560 +81,12 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
});
}
-void ASTDumper::dumpAttr(const Attr *A) {
- dumpChild([=] {
- NodeDumper.Visit(A);
- ConstAttrVisitor<ASTDumper>::Visit(A);
- });
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Utilities
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
- dumpChild([=] {
- NodeDumper.Visit(Init);
- dumpStmt(Init->getInit());
- });
-}
-
-void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
- if (!TPL)
- return;
-
- for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I)
- dumpDecl(*I);
-}
-
-void ASTDumper::dumpTemplateArgumentListInfo(
- const TemplateArgumentListInfo &TALI) {
- for (unsigned i = 0, e = TALI.size(); i < e; ++i)
- dumpTemplateArgumentLoc(TALI[i]);
-}
-
-void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
- const Decl *From, const char *Label) {
- dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label);
-}
-
-void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
- for (unsigned i = 0, e = TAL.size(); i < e; ++i)
- dumpTemplateArgument(TAL[i]);
-}
-
-void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R,
- const Decl *From, const char *Label) {
- dumpChild([=] {
- NodeDumper.Visit(A, R, From, Label);
- ConstTemplateArgumentVisitor<ASTDumper>::Visit(A);
- });
-}
-
-//===----------------------------------------------------------------------===//
-// Objective-C Utilities
-//===----------------------------------------------------------------------===//
-void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
- if (!typeParams)
- return;
-
- for (auto typeParam : *typeParams) {
- dumpDecl(typeParam);
- }
-}
-
-//===----------------------------------------------------------------------===//
-// Decl dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpDecl(const Decl *D) {
- dumpChild([=] {
- NodeDumper.Visit(D);
- if (!D)
- return;
-
- ConstDeclVisitor<ASTDumper>::Visit(D);
-
- for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
- ++I)
- dumpAttr(*I);
-
- if (const FullComment *Comment =
- D->getASTContext().getLocalCommentForDeclUncached(D))
- dumpComment(Comment, Comment);
-
- // Decls within functions are visited by the body.
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
- auto DC = dyn_cast<DeclContext>(D);
- if (DC &&
- (DC->hasExternalLexicalStorage() ||
- (Deserialize ? DC->decls_begin() != DC->decls_end()
- : DC->noload_decls_begin() != DC->noload_decls_end())))
- dumpDeclContext(DC);
- }
- });
-}
-
-void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); }
-
-void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getUnderlyingType());
- if (D->isModulePrivate())
- OS << " __module_private__";
- dumpTypeAsChild(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
- if (D->isScoped()) {
- if (D->isScopedUsingClassTag())
- OS << " class";
- else
- OS << " struct";
- }
- NodeDumper.dumpName(D);
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isFixed())
- NodeDumper.dumpType(D->getIntegerType());
-}
-
-void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
- OS << ' ' << D->getKindName();
- NodeDumper.dumpName(D);
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isCompleteDefinition())
- OS << " definition";
-}
-
-void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (const Expr *Init = D->getInitExpr())
- dumpStmt(Init);
-}
-
-void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- for (auto *Child : D->chain())
- NodeDumper.dumpDeclRef(Child);
-}
-
-void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- StorageClass SC = D->getStorageClass();
- if (SC != SC_None)
- OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
- if (D->isInlineSpecified())
- OS << " inline";
- if (D->isVirtualAsWritten())
- OS << " virtual";
- if (D->isModulePrivate())
- OS << " __module_private__";
-
- if (D->isPure())
- OS << " pure";
- if (D->isDefaulted()) {
- OS << " default";
- if (D->isDeleted())
- OS << "_delete";
- }
- if (D->isDeletedAsWritten())
- OS << " delete";
- if (D->isTrivial())
- OS << " trivial";
-
- if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) {
- FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- switch (EPI.ExceptionSpec.Type) {
- default: break;
- case EST_Unevaluated:
- OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
- break;
- case EST_Uninstantiated:
- OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
- break;
- }
- }
-
- if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
- if (MD->size_overridden_methods() != 0) {
- auto dumpOverride = [=](const CXXMethodDecl *D) {
- SplitQualType T_split = D->getType().split();
- OS << D << " " << D->getParent()->getName()
- << "::" << D->getNameAsString() << " '"
- << QualType::getAsString(T_split, PrintPolicy) << "'";
- };
-
- dumpChild([=] {
- auto Overrides = MD->overridden_methods();
- OS << "Overrides: [ ";
- dumpOverride(*Overrides.begin());
- for (const auto *Override :
- llvm::make_range(Overrides.begin() + 1, Overrides.end())) {
- OS << ", ";
- dumpOverride(Override);
- }
- OS << " ]";
- });
- }
- }
-
- if (const auto *FTSI = D->getTemplateSpecializationInfo())
- dumpTemplateArgumentList(*FTSI->TemplateArguments);
-
- if (!D->param_begin() && D->getNumParams())
- dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
- else
- for (const ParmVarDecl *Parameter : D->parameters())
- dumpDecl(Parameter);
-
- if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
- for (const auto *I : C->inits())
- dumpCXXCtorInitializer(I);
-
- if (D->doesThisDeclarationHaveABody())
- dumpStmt(D->getBody());
-}
-
-void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (D->isMutable())
- OS << " mutable";
- if (D->isModulePrivate())
- OS << " __module_private__";
-
- if (D->isBitField())
- dumpStmt(D->getBitWidth());
- if (Expr *Init = D->getInClassInitializer())
- dumpStmt(Init);
-}
-
-void ASTDumper::VisitVarDecl(const VarDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- StorageClass SC = D->getStorageClass();
- if (SC != SC_None)
- OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
- switch (D->getTLSKind()) {
- case VarDecl::TLS_None: break;
- case VarDecl::TLS_Static: OS << " tls"; break;
- case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
- }
- if (D->isModulePrivate())
- OS << " __module_private__";
- if (D->isNRVOVariable())
- OS << " nrvo";
- if (D->isInline())
- OS << " inline";
- if (D->isConstexpr())
- OS << " constexpr";
- if (D->hasInit()) {
- switch (D->getInitStyle()) {
- case VarDecl::CInit: OS << " cinit"; break;
- case VarDecl::CallInit: OS << " callinit"; break;
- case VarDecl::ListInit: OS << " listinit"; break;
- }
- dumpStmt(D->getInit());
- }
-}
-
-void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) {
- VisitVarDecl(D);
- for (auto *B : D->bindings())
- dumpDecl(B);
-}
-
-void ASTDumper::VisitBindingDecl(const BindingDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (auto *E = D->getBinding())
- dumpStmt(E);
-}
-
-void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
- dumpStmt(D->getAsmString());
-}
-
-void ASTDumper::VisitImportDecl(const ImportDecl *D) {
- OS << ' ' << D->getImportedModule()->getFullModuleName();
-}
-
-void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) {
- OS << ' ';
- switch (D->getCommentKind()) {
- case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind");
- case PCK_Compiler: OS << "compiler"; break;
- case PCK_ExeStr: OS << "exestr"; break;
- case PCK_Lib: OS << "lib"; break;
- case PCK_Linker: OS << "linker"; break;
- case PCK_User: OS << "user"; break;
- }
- StringRef Arg = D->getArg();
- if (!Arg.empty())
- OS << " \"" << Arg << "\"";
-}
-
-void ASTDumper::VisitPragmaDetectMismatchDecl(
- const PragmaDetectMismatchDecl *D) {
- OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\"";
-}
-
-void ASTDumper::VisitCapturedDecl(const CapturedDecl *D) {
- dumpStmt(D->getBody());
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
- for (auto *E : D->varlists())
- dumpStmt(E);
-}
-
-void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- OS << " combiner";
- NodeDumper.dumpPointer(D->getCombiner());
- if (const auto *Initializer = D->getInitializer()) {
- OS << " initializer";
- NodeDumper.dumpPointer(Initializer);
- switch (D->getInitializerKind()) {
- case OMPDeclareReductionDecl::DirectInit:
- OS << " omp_priv = ";
- break;
- case OMPDeclareReductionDecl::CopyInit:
- OS << " omp_priv ()";
- break;
- case OMPDeclareReductionDecl::CallInit:
- break;
- }
- }
-
- dumpStmt(D->getCombiner());
- if (const auto *Initializer = D->getInitializer())
- dumpStmt(Initializer);
-}
-
-void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) {
- for (auto *C : D->clauselists()) {
- dumpChild([=] {
- if (!C) {
- ColorScope Color(OS, ShowColors, NullColor);
- OS << "<<<NULL>>> OMPClause";
- return;
- }
- {
- ColorScope Color(OS, ShowColors, AttrColor);
- StringRef ClauseName(getOpenMPClauseName(C->getClauseKind()));
- OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper()
- << ClauseName.drop_front() << "Clause";
- }
- NodeDumper.dumpPointer(C);
- NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc()));
- });
- }
-}
-
-void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- dumpStmt(D->getInit());
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
- NodeDumper.dumpName(D);
- if (D->isInline())
- OS << " inline";
- if (!D->isOriginalNamespace())
- NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original");
-}
-
-void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getNominatedNamespace());
-}
-
-void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getAliasedNamespace());
-}
-
-void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getUnderlyingType());
- dumpTypeAsChild(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
-}
-
-void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
- VisitRecordDecl(D);
- if (!D->isCompleteDefinition())
- return;
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "DefinitionData";
- }
-#define FLAG(fn, name) if (D->fn()) OS << " " #name;
- FLAG(isParsingBaseSpecifiers, parsing_base_specifiers);
-
- FLAG(isGenericLambda, generic);
- FLAG(isLambda, lambda);
-
- FLAG(canPassInRegisters, pass_in_registers);
- FLAG(isEmpty, empty);
- FLAG(isAggregate, aggregate);
- FLAG(isStandardLayout, standard_layout);
- FLAG(isTriviallyCopyable, trivially_copyable);
- FLAG(isPOD, pod);
- FLAG(isTrivial, trivial);
- FLAG(isPolymorphic, polymorphic);
- FLAG(isAbstract, abstract);
- FLAG(isLiteral, literal);
-
- FLAG(hasUserDeclaredConstructor, has_user_declared_ctor);
- FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor);
- FLAG(hasMutableFields, has_mutable_fields);
- FLAG(hasVariantMembers, has_variant_members);
- FLAG(allowConstDefaultInit, can_const_default_init);
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "DefaultConstructor";
- }
- FLAG(hasDefaultConstructor, exists);
- FLAG(hasTrivialDefaultConstructor, trivial);
- FLAG(hasNonTrivialDefaultConstructor, non_trivial);
- FLAG(hasUserProvidedDefaultConstructor, user_provided);
- FLAG(hasConstexprDefaultConstructor, constexpr);
- FLAG(needsImplicitDefaultConstructor, needs_implicit);
- FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "CopyConstructor";
- }
- FLAG(hasSimpleCopyConstructor, simple);
- FLAG(hasTrivialCopyConstructor, trivial);
- FLAG(hasNonTrivialCopyConstructor, non_trivial);
- FLAG(hasUserDeclaredCopyConstructor, user_declared);
- FLAG(hasCopyConstructorWithConstParam, has_const_param);
- FLAG(needsImplicitCopyConstructor, needs_implicit);
- FLAG(needsOverloadResolutionForCopyConstructor,
- needs_overload_resolution);
- if (!D->needsOverloadResolutionForCopyConstructor())
- FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted);
- FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "MoveConstructor";
- }
- FLAG(hasMoveConstructor, exists);
- FLAG(hasSimpleMoveConstructor, simple);
- FLAG(hasTrivialMoveConstructor, trivial);
- FLAG(hasNonTrivialMoveConstructor, non_trivial);
- FLAG(hasUserDeclaredMoveConstructor, user_declared);
- FLAG(needsImplicitMoveConstructor, needs_implicit);
- FLAG(needsOverloadResolutionForMoveConstructor,
- needs_overload_resolution);
- if (!D->needsOverloadResolutionForMoveConstructor())
- FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "CopyAssignment";
- }
- FLAG(hasTrivialCopyAssignment, trivial);
- FLAG(hasNonTrivialCopyAssignment, non_trivial);
- FLAG(hasCopyAssignmentWithConstParam, has_const_param);
- FLAG(hasUserDeclaredCopyAssignment, user_declared);
- FLAG(needsImplicitCopyAssignment, needs_implicit);
- FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution);
- FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "MoveAssignment";
- }
- FLAG(hasMoveAssignment, exists);
- FLAG(hasSimpleMoveAssignment, simple);
- FLAG(hasTrivialMoveAssignment, trivial);
- FLAG(hasNonTrivialMoveAssignment, non_trivial);
- FLAG(hasUserDeclaredMoveAssignment, user_declared);
- FLAG(needsImplicitMoveAssignment, needs_implicit);
- FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution);
- });
-
- dumpChild([=] {
- {
- ColorScope Color(OS, ShowColors, DeclKindNameColor);
- OS << "Destructor";
- }
- FLAG(hasSimpleDestructor, simple);
- FLAG(hasIrrelevantDestructor, irrelevant);
- FLAG(hasTrivialDestructor, trivial);
- FLAG(hasNonTrivialDestructor, non_trivial);
- FLAG(hasUserDeclaredDestructor, user_declared);
- FLAG(needsImplicitDestructor, needs_implicit);
- FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution);
- if (!D->needsOverloadResolutionForDestructor())
- FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted);
- });
- });
-
- for (const auto &I : D->bases()) {
- dumpChild([=] {
- if (I.isVirtual())
- OS << "virtual ";
- NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier());
- NodeDumper.dumpType(I.getType());
- if (I.isPackExpansion())
- OS << "...";
- });
- }
-}
-
-void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
- dumpStmt(D->getAssertExpr());
- dumpStmt(D->getMessage());
-}
-
template <typename SpecializationDecl>
void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
bool DumpExplicitInst,
bool DumpRefOnly) {
bool DumpedAny = false;
- for (auto *RedeclWithBadType : D->redecls()) {
+ for (const auto *RedeclWithBadType : D->redecls()) {
// FIXME: The redecls() range sometimes has elements of a less-specific
// type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
// us TagDecls, and should give CXXRecordDecls).
@@ -1007,7 +110,7 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
if (DumpRefOnly)
NodeDumper.dumpDeclRef(Redecl);
else
- dumpDecl(Redecl);
+ Visit(Redecl);
DumpedAny = true;
break;
case TSK_ExplicitSpecialization:
@@ -1022,12 +125,11 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
template <typename TemplateDecl>
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
- NodeDumper.dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
+ Visit(D->getTemplatedDecl());
- for (auto *Child : D->specializations())
+ for (const auto *Child : D->specializations())
dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
!D->isCanonicalDecl());
}
@@ -1043,500 +145,10 @@ void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
dumpTemplateDecl(D, false);
}
-void ASTDumper::VisitClassTemplateSpecializationDecl(
- const ClassTemplateSpecializationDecl *D) {
- VisitCXXRecordDecl(D);
- dumpTemplateArgumentList(D->getTemplateArgs());
-}
-
-void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
- const ClassTemplatePartialSpecializationDecl *D) {
- VisitClassTemplateSpecializationDecl(D);
- dumpTemplateParameters(D->getTemplateParameters());
-}
-
-void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
- const ClassScopeFunctionSpecializationDecl *D) {
- dumpDecl(D->getSpecialization());
- if (D->hasExplicitTemplateArgs())
- dumpTemplateArgumentListInfo(D->templateArgs());
-}
-
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
dumpTemplateDecl(D, false);
}
-void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
-}
-
-void ASTDumper::VisitVarTemplateSpecializationDecl(
- const VarTemplateSpecializationDecl *D) {
- dumpTemplateArgumentList(D->getTemplateArgs());
- VisitVarDecl(D);
-}
-
-void ASTDumper::VisitVarTemplatePartialSpecializationDecl(
- const VarTemplatePartialSpecializationDecl *D) {
- dumpTemplateParameters(D->getTemplateParameters());
- VisitVarTemplateSpecializationDecl(D);
-}
-
-void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
- if (D->wasDeclaredWithTypename())
- OS << " typename";
- else
- OS << " class";
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
- D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from"
- : "previous");
-}
-
-void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
- NodeDumper.dumpType(D->getType());
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- if (D->hasDefaultArgument())
- dumpTemplateArgument(D->getDefaultArgument(), SourceRange(),
- D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from"
- : "previous");
-}
-
-void ASTDumper::VisitTemplateTemplateParmDecl(
- const TemplateTemplateParmDecl *D) {
- OS << " depth " << D->getDepth() << " index " << D->getIndex();
- if (D->isParameterPack())
- OS << " ...";
- NodeDumper.dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- if (D->hasDefaultArgument())
- dumpTemplateArgumentLoc(
- D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
- D->defaultArgumentWasInherited() ? "inherited from" : "previous");
-}
-
-void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
-}
-
-void ASTDumper::VisitUnresolvedUsingTypenameDecl(
- const UnresolvedUsingTypenameDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
-}
-
-void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
- OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
- OS << D->getNameAsString();
- NodeDumper.dumpType(D->getType());
-}
-
-void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getTargetDecl());
- if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
- dumpTypeAsChild(TD->getTypeForDecl());
-}
-
-void ASTDumper::VisitConstructorUsingShadowDecl(
- const ConstructorUsingShadowDecl *D) {
- if (D->constructsVirtualBase())
- OS << " virtual";
-
- dumpChild([=] {
- OS << "target ";
- NodeDumper.dumpBareDeclRef(D->getTargetDecl());
- });
-
- dumpChild([=] {
- OS << "nominated ";
- NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass());
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl());
- });
-
- dumpChild([=] {
- OS << "constructed ";
- NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass());
- OS << ' ';
- NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl());
- });
-}
-
-void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
- switch (D->getLanguage()) {
- case LinkageSpecDecl::lang_c: OS << " C"; break;
- case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
- }
-}
-
-void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
- OS << ' ';
- NodeDumper.dumpAccessSpecifier(D->getAccess());
-}
-
-void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
- if (TypeSourceInfo *T = D->getFriendType())
- NodeDumper.dumpType(T->getType());
- else
- dumpDecl(D->getFriendDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// Obj-C Declarations
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
- if (D->getSynthesize())
- OS << " synthesize";
-
- switch (D->getAccessControl()) {
- case ObjCIvarDecl::None:
- OS << " none";
- break;
- case ObjCIvarDecl::Private:
- OS << " private";
- break;
- case ObjCIvarDecl::Protected:
- OS << " protected";
- break;
- case ObjCIvarDecl::Public:
- OS << " public";
- break;
- case ObjCIvarDecl::Package:
- OS << " package";
- break;
- }
-}
-
-void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
- if (D->isInstanceMethod())
- OS << " -";
- else
- OS << " +";
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getReturnType());
-
- if (D->isThisDeclarationADefinition()) {
- dumpDeclContext(D);
- } else {
- for (const ParmVarDecl *Parameter : D->parameters())
- dumpDecl(Parameter);
- }
-
- if (D->isVariadic())
- dumpChild([=] { OS << "..."; });
-
- if (D->hasBody())
- dumpStmt(D->getBody());
-}
-
-void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
- NodeDumper.dumpName(D);
- switch (D->getVariance()) {
- case ObjCTypeParamVariance::Invariant:
- break;
-
- case ObjCTypeParamVariance::Covariant:
- OS << " covariant";
- break;
-
- case ObjCTypeParamVariance::Contravariant:
- OS << " contravariant";
- break;
- }
-
- if (D->hasExplicitBound())
- OS << " bounded";
- NodeDumper.dumpType(D->getUnderlyingType());
-}
-
-void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
- NodeDumper.dumpDeclRef(D->getImplementation());
- for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I)
- NodeDumper.dumpDeclRef(*I);
- dumpObjCTypeParamList(D->getTypeParamList());
-}
-
-void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
- NodeDumper.dumpDeclRef(D->getCategoryDecl());
-}
-
-void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
- NodeDumper.dumpName(D);
-
- for (auto *Child : D->protocols())
- NodeDumper.dumpDeclRef(Child);
-}
-
-void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
-
- NodeDumper.dumpDeclRef(D->getImplementation());
- for (auto *Child : D->protocols())
- NodeDumper.dumpDeclRef(Child);
- dumpObjCTypeParamList(D->getTypeParamListAsWritten());
-}
-
-void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getSuperClass(), "super");
- NodeDumper.dumpDeclRef(D->getClassInterface());
- for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
- E = D->init_end();
- I != E; ++I)
- dumpCXXCtorInitializer(*I);
-}
-
-void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpDeclRef(D->getClassInterface());
-}
-
-void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
- NodeDumper.dumpName(D);
- NodeDumper.dumpType(D->getType());
-
- if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
- OS << " required";
- else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
- OS << " optional";
-
- ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
- if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
- if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
- OS << " readonly";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
- OS << " assign";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
- OS << " readwrite";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
- OS << " retain";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
- OS << " copy";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
- OS << " nonatomic";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
- OS << " atomic";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
- OS << " weak";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
- OS << " strong";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
- OS << " unsafe_unretained";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_class)
- OS << " class";
- if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
- NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter");
- if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
- NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter");
- }
-}
-
-void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
- NodeDumper.dumpName(D->getPropertyDecl());
- if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
- OS << " synthesize";
- else
- OS << " dynamic";
- NodeDumper.dumpDeclRef(D->getPropertyDecl());
- NodeDumper.dumpDeclRef(D->getPropertyIvarDecl());
-}
-
-void ASTDumper::Visit(const BlockDecl::Capture &C) {
- dumpChild([=] {
- NodeDumper.Visit(C);
- if (C.hasCopyExpr())
- dumpStmt(C.getCopyExpr());
- });
-}
-
-void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
- for (auto I : D->parameters())
- dumpDecl(I);
-
- if (D->isVariadic())
- dumpChild([=]{ OS << "..."; });
-
- if (D->capturesCXXThis())
- dumpChild([=]{ OS << "capture this"; });
-
- for (const auto &I : D->captures())
- Visit(I);
- dumpStmt(D->getBody());
-}
-
-//===----------------------------------------------------------------------===//
-// Stmt dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) {
- dumpChild(Label, [=] {
- NodeDumper.Visit(S);
-
- if (!S) {
- return;
- }
-
- ConstStmtVisitor<ASTDumper>::Visit(S);
-
- // Some statements have custom mechanisms for dumping their children.
- if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) {
- return;
- }
-
- for (const Stmt *SubStmt : S->children())
- dumpStmt(SubStmt);
- });
-}
-
-void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
- for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
- E = Node->decl_end();
- I != E; ++I)
- dumpDecl(*I);
-}
-
-void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
- for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
- E = Node->getAttrs().end();
- I != E; ++I)
- dumpAttr(*I);
-}
-
-void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
- dumpDecl(Node->getExceptionDecl());
-}
-
-void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) {
- dumpDecl(Node->getCapturedDecl());
-}
-
-//===----------------------------------------------------------------------===//
-// OpenMP dumping methods.
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::Visit(const OMPClause *C) {
- dumpChild([=] {
- NodeDumper.Visit(C);
- for (auto *S : C->children())
- dumpStmt(S);
- });
-}
-
-void ASTDumper::VisitOMPExecutableDirective(
- const OMPExecutableDirective *Node) {
- for (const auto *C : Node->clauses())
- Visit(C);
-}
-
-//===----------------------------------------------------------------------===//
-// Expr dumping methods.
-//===----------------------------------------------------------------------===//
-
-
-void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
- if (auto *Filler = ILE->getArrayFiller()) {
- dumpStmt(Filler, "array_filler");
- }
-}
-
-void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
- dumpDecl(Node->getBlockDecl());
-}
-
-void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
- if (Expr *Source = Node->getSourceExpr())
- dumpStmt(Source);
-}
-
-void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
- if (E->isResultDependent())
- OS << " result_dependent";
- dumpStmt(E->getControllingExpr());
- dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove
-
- for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
- dumpChild([=] {
- if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) {
- OS << "case ";
- NodeDumper.dumpType(TSI->getType());
- } else {
- OS << "default";
- }
-
- if (!E->isResultDependent() && E->getResultIndex() == I)
- OS << " selected";
-
- if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I))
- dumpTypeAsChild(TSI->getType());
- dumpStmt(E->getAssocExpr(I));
- });
- }
-}
-
-//===----------------------------------------------------------------------===//
-// C++ Expressions
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
- if (Node->isPartiallySubstituted())
- for (const auto &A : Node->getPartialArguments())
- dumpTemplateArgument(A);
-}
-
-//===----------------------------------------------------------------------===//
-// Obj-C Expressions
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
- if (const VarDecl *CatchParam = Node->getCatchParamDecl())
- dumpDecl(CatchParam);
-}
-
-//===----------------------------------------------------------------------===//
-// Comments
-//===----------------------------------------------------------------------===//
-
-void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) {
- dumpChild([=] {
- NodeDumper.Visit(C, FC);
- if (!C) {
- return;
- }
- ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC);
- for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
- I != E; ++I)
- dumpComment(*I, FC);
- });
-}
-
//===----------------------------------------------------------------------===//
// Type method implementations
//===----------------------------------------------------------------------===//
@@ -1551,7 +163,7 @@ LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
ASTDumper Dumper(OS, nullptr, nullptr);
- Dumper.dumpTypeAsChild(*this);
+ Dumper.Visit(*this);
}
LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
@@ -1566,13 +178,22 @@ LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
-LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const {
- const ASTContext &Ctx = getASTContext();
+LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
+ ASTDumpOutputFormat Format) const {
+ ASTContext &Ctx = getASTContext();
const SourceManager &SM = Ctx.getSourceManager();
- ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
- SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
- P.setDeserialize(Deserialize);
- P.dumpDecl(this);
+
+ if (ADOF_JSON == Format) {
+ JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
+ &Ctx.getCommentCommandTraits());
+ (void)Deserialize; // FIXME?
+ P.Visit(this);
+ } else {
+ ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
+ SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
+ P.setDeserialize(Deserialize);
+ P.Visit(this);
+ }
}
LLVM_DUMP_METHOD void Decl::dumpColor() const {
@@ -1580,7 +201,7 @@ LLVM_DUMP_METHOD void Decl::dumpColor() const {
ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
&Ctx.getSourceManager(), /*ShowColors*/ true,
Ctx.getPrintingPolicy());
- P.dumpDecl(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
@@ -1611,22 +232,22 @@ LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
ASTDumper P(OS, nullptr, &SM);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
ASTDumper P(OS, nullptr, nullptr);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dump() const {
ASTDumper P(llvm::errs(), nullptr, nullptr);
- P.dumpStmt(this);
+ P.Visit(this);
}
LLVM_DUMP_METHOD void Stmt::dumpColor() const {
ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
- P.dumpStmt(this);
+ P.Visit(this);
}
//===----------------------------------------------------------------------===//
@@ -1648,7 +269,7 @@ void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
if (!FC)
return;
ASTDumper D(OS, Traits, SM);
- D.dumpComment(FC, FC);
+ D.Visit(FC, FC);
}
LLVM_DUMP_METHOD void Comment::dumpColor() const {
@@ -1656,5 +277,5 @@ LLVM_DUMP_METHOD void Comment::dumpColor() const {
if (!FC)
return;
ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
- D.dumpComment(FC, FC);
+ D.Visit(FC, FC);
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 44832557e97b..9d5dd84161de 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1,9 +1,8 @@
//===- ASTImporter.cpp - Importing ASTs from other Contexts ---------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTImporter.h"
-#include "clang/AST/ASTImporterLookupTable.h"
+#include "clang/AST/ASTImporterSharedState.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTStructuralEquivalence.h"
@@ -58,6 +57,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
@@ -135,25 +135,6 @@ namespace clang {
To->setIsUsed();
}
- // FIXME: Temporary until every import returns Expected.
- template <>
- LLVM_NODISCARD Error
- ASTImporter::importInto(SourceLocation &To, const SourceLocation &From) {
- To = Import(From);
- if (From.isValid() && To.isInvalid())
- return llvm::make_error<ImportError>();
- return Error::success();
- }
- // FIXME: Temporary until every import returns Expected.
- template <>
- LLVM_NODISCARD Error
- ASTImporter::importInto(QualType &To, const QualType &From) {
- To = Import(From);
- if (!From.isNull() && To.isNull())
- return llvm::make_error<ImportError>();
- return Error::success();
- }
-
class ASTNodeImporter : public TypeVisitor<ASTNodeImporter, ExpectedType>,
public DeclVisitor<ASTNodeImporter, ExpectedDecl>,
public StmtVisitor<ASTNodeImporter, ExpectedStmt> {
@@ -168,32 +149,20 @@ namespace clang {
// Use this to import pointers of specific type.
template <typename ImportT>
LLVM_NODISCARD Error importInto(ImportT *&To, ImportT *From) {
- auto ToI = Importer.Import(From);
- if (!ToI && From)
- return make_error<ImportError>();
- To = cast_or_null<ImportT>(ToI);
- return Error::success();
- // FIXME: This should be the final code.
- //auto ToOrErr = Importer.Import(From);
- //if (ToOrErr) {
- // To = cast_or_null<ImportT>(*ToOrErr);
- //}
- //return ToOrErr.takeError();
+ auto ToOrErr = Importer.Import(From);
+ if (ToOrErr)
+ To = cast_or_null<ImportT>(*ToOrErr);
+ return ToOrErr.takeError();
}
// Call the import function of ASTImporter for a baseclass of type `T` and
// cast the return value to `T`.
template <typename T>
Expected<T *> import(T *From) {
- auto *To = Importer.Import(From);
- if (!To && From)
- return make_error<ImportError>();
- return cast_or_null<T>(To);
- // FIXME: This should be the final code.
- //auto ToOrErr = Importer.Import(From);
- //if (!ToOrErr)
- // return ToOrErr.takeError();
- //return cast_or_null<T>(*ToOrErr);
+ auto ToOrErr = Importer.Import(From);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ return cast_or_null<T>(*ToOrErr);
}
template <typename T>
@@ -204,13 +173,15 @@ namespace clang {
// Call the import function of ASTImporter for type `T`.
template <typename T>
Expected<T> import(const T &From) {
- T To = Importer.Import(From);
- T DefaultT;
- if (To == DefaultT && !(From == DefaultT))
- return make_error<ImportError>();
- return To;
- // FIXME: This should be the final code.
- //return Importer.Import(From);
+ return Importer.Import(From);
+ }
+
+ // Import an Optional<T> by importing the contained T, if any.
+ template<typename T>
+ Expected<Optional<T>> import(Optional<T> From) {
+ if (!From)
+ return Optional<T>();
+ return import(*From);
}
template <class T>
@@ -283,18 +254,16 @@ 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.
- //}
+ 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);
+ Importer.RegisterImportedDecl(FromD, ToD);
InitializeImportedDecl(FromD, ToD);
return false; // A new Decl is created.
}
@@ -302,14 +271,31 @@ namespace clang {
void InitializeImportedDecl(Decl *FromD, Decl *ToD) {
ToD->IdentifierNamespace = FromD->IdentifierNamespace;
if (FromD->hasAttrs())
- for (const Attr *FromAttr : FromD->getAttrs())
- ToD->addAttr(Importer.Import(FromAttr));
+ for (const Attr *FromAttr : FromD->getAttrs()) {
+ // FIXME: Return of the error here is not possible until store of
+ // import errors is implemented.
+ auto ToAttrOrErr = import(FromAttr);
+ if (ToAttrOrErr)
+ ToD->addAttr(*ToAttrOrErr);
+ else
+ llvm::consumeError(ToAttrOrErr.takeError());
+ }
if (FromD->isUsed())
ToD->setIsUsed();
if (FromD->isImplicit())
ToD->setImplicit();
}
+ // Check if we have found an existing definition. Returns with that
+ // definition if yes, otherwise returns null.
+ Decl *FindAndMapDefinition(FunctionDecl *D, FunctionDecl *FoundFunction) {
+ const FunctionDecl *Definition = nullptr;
+ if (D->doesThisDeclarationHaveABody() &&
+ FoundFunction->hasBody(Definition))
+ return Importer.MapImported(D, const_cast<FunctionDecl *>(Definition));
+ return nullptr;
+ }
+
public:
explicit ASTNodeImporter(ASTImporter &Importer) : Importer(Importer) {}
@@ -412,8 +398,6 @@ namespace clang {
Error ImportDefinition(
ObjCProtocolDecl *From, ObjCProtocolDecl *To,
ImportDefinitionKind Kind = IDK_Default);
- Expected<TemplateParameterList *> ImportTemplateParameterList(
- TemplateParameterList *Params);
Error ImportTemplateArguments(
const TemplateArgument *FromArgs, unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs);
@@ -435,9 +419,16 @@ namespace clang {
Expected<FunctionTemplateAndArgsTy>
ImportFunctionTemplateWithTemplateArgsFromSpecialization(
FunctionDecl *FromFD);
+ Error ImportTemplateParameterLists(const DeclaratorDecl *FromD,
+ DeclaratorDecl *ToD);
Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
+ Error ImportFunctionDeclBody(FunctionDecl *FromFD, FunctionDecl *ToFD);
+
+ template <typename T>
+ bool hasSameVisibilityContext(T *Found, T *From);
+
bool IsStructuralMatch(Decl *From, Decl *To, bool Complain);
bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
bool Complain = true);
@@ -548,6 +539,7 @@ namespace clang {
// Importing expressions
ExpectedStmt VisitExpr(Expr *E);
ExpectedStmt VisitVAArgExpr(VAArgExpr *E);
+ ExpectedStmt VisitChooseExpr(ChooseExpr *E);
ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E);
ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E);
ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E);
@@ -649,15 +641,6 @@ namespace clang {
FunctionDecl *FromFD);
};
-// FIXME: Temporary until every import returns Expected.
-template <>
-Expected<TemplateName> ASTNodeImporter::import(const TemplateName &From) {
- TemplateName To = Importer.Import(From);
- if (To.isNull() && !From.isNull())
- return make_error<ImportError>();
- return To;
-}
-
template <typename InContainerTy>
Error ASTNodeImporter::ImportTemplateArgumentListInfo(
SourceLocation FromLAngleLoc, SourceLocation FromRAngleLoc,
@@ -1649,16 +1632,32 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
auto ToDCOrErr = Importer.ImportContext(FromDC);
return ToDCOrErr.takeError();
}
+
+ // We use strict error handling in case of records and enums, but not
+ // with e.g. namespaces.
+ //
+ // FIXME Clients of the ASTImporter should be able to choose an
+ // appropriate error handling strategy for their needs. For instance,
+ // they may not want to mark an entire namespace as erroneous merely
+ // because there is an ODR error with two typedefs. As another example,
+ // the client may allow EnumConstantDecls with same names but with
+ // different values in two distinct translation units.
+ bool AccumulateChildErrors = isa<TagDecl>(FromDC);
+
+ Error ChildErrors = Error::success();
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());
+ if (!ImportedOrErr) {
+ if (AccumulateChildErrors)
+ ChildErrors =
+ joinErrors(std::move(ChildErrors), ImportedOrErr.takeError());
+ else
+ consumeError(ImportedOrErr.takeError());
+ }
}
- return Error::success();
+ return ChildErrors;
}
Error ASTNodeImporter::ImportDeclContext(
@@ -1698,29 +1697,50 @@ Error ASTNodeImporter::ImportImplicitMethods(
static Error setTypedefNameForAnonDecl(TagDecl *From, TagDecl *To,
ASTImporter &Importer) {
if (TypedefNameDecl *FromTypedef = From->getTypedefNameForAnonDecl()) {
- Decl *ToTypedef = Importer.Import(FromTypedef);
- if (!ToTypedef)
- return make_error<ImportError>();
- To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(ToTypedef));
- // FIXME: This should be the final code.
- //if (Expected<Decl *> ToTypedefOrErr = Importer.Import(FromTypedef))
- // To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
- //else
- // return ToTypedefOrErr.takeError();
+ if (ExpectedDecl ToTypedefOrErr = Importer.Import(FromTypedef))
+ To->setTypedefNameForAnonDecl(cast<TypedefNameDecl>(*ToTypedefOrErr));
+ else
+ return ToTypedefOrErr.takeError();
}
return Error::success();
}
Error ASTNodeImporter::ImportDefinition(
RecordDecl *From, RecordDecl *To, ImportDefinitionKind Kind) {
+ auto DefinitionCompleter = [To]() {
+ // There are cases in LLDB when we first import a class without its
+ // members. The class will have DefinitionData, but no members. Then,
+ // importDefinition is called from LLDB, which tries to get the members, so
+ // when we get here, the class already has the DefinitionData set, so we
+ // must unset the CompleteDefinition here to be able to complete again the
+ // definition.
+ To->setCompleteDefinition(false);
+ To->completeDefinition();
+ };
+
if (To->getDefinition() || To->isBeingDefined()) {
- if (Kind == IDK_Everything)
- return ImportDeclContext(From, /*ForceImport=*/true);
+ if (Kind == IDK_Everything ||
+ // In case of lambdas, the class already has a definition ptr set, but
+ // the contained decls are not imported yet. Also, isBeingDefined was
+ // set in CXXRecordDecl::CreateLambda. We must import the contained
+ // decls here and finish the definition.
+ (To->isLambda() && shouldForceImportDeclContext(Kind))) {
+ Error Result = ImportDeclContext(From, /*ForceImport=*/true);
+ // Finish the definition of the lambda, set isBeingDefined to false.
+ if (To->isLambda())
+ DefinitionCompleter();
+ return Result;
+ }
return Error::success();
}
To->startDefinition();
+ // Complete the definition even if error is returned.
+ // The RecordDecl may be already part of the AST so it is better to
+ // have it in complete state even if something is wrong with it.
+ auto DefinitionCompleterScopeExit =
+ llvm::make_scope_exit(DefinitionCompleter);
if (Error Err = setTypedefNameForAnonDecl(From, To, Importer))
return Err;
@@ -1798,6 +1818,9 @@ Error ASTNodeImporter::ImportDefinition(
ToData.HasDeclaredCopyAssignmentWithConstParam
= FromData.HasDeclaredCopyAssignmentWithConstParam;
+ // Copy over the data stored in RecordDeclBits
+ ToCXX->setArgPassingRestrictions(FromCXX->getArgPassingRestrictions());
+
SmallVector<CXXBaseSpecifier *, 4> Bases;
for (const auto &Base1 : FromCXX->bases()) {
ExpectedType TyOrErr = import(Base1.getType());
@@ -1842,7 +1865,6 @@ Error ASTNodeImporter::ImportDefinition(
if (Error Err = ImportDeclContext(From, /*ForceImport=*/true))
return Err;
- To->completeDefinition();
return Error::success();
}
@@ -1903,40 +1925,6 @@ Error ASTNodeImporter::ImportDefinition(
return Error::success();
}
-// FIXME: Remove this, use `import` instead.
-Expected<TemplateParameterList *> ASTNodeImporter::ImportTemplateParameterList(
- TemplateParameterList *Params) {
- SmallVector<NamedDecl *, 4> ToParams(Params->size());
- if (Error Err = ImportContainerChecked(*Params, ToParams))
- return std::move(Err);
-
- Expr *ToRequiresClause;
- if (Expr *const R = Params->getRequiresClause()) {
- if (Error Err = importInto(ToRequiresClause, R))
- return std::move(Err);
- } else {
- ToRequiresClause = nullptr;
- }
-
- auto ToTemplateLocOrErr = import(Params->getTemplateLoc());
- if (!ToTemplateLocOrErr)
- return ToTemplateLocOrErr.takeError();
- auto ToLAngleLocOrErr = import(Params->getLAngleLoc());
- if (!ToLAngleLocOrErr)
- return ToLAngleLocOrErr.takeError();
- auto ToRAngleLocOrErr = import(Params->getRAngleLoc());
- if (!ToRAngleLocOrErr)
- return ToRAngleLocOrErr.takeError();
-
- return TemplateParameterList::Create(
- Importer.getToContext(),
- *ToTemplateLocOrErr,
- *ToLAngleLocOrErr,
- ToParams,
- *ToRAngleLocOrErr,
- ToRequiresClause);
-}
-
Error ASTNodeImporter::ImportTemplateArguments(
const TemplateArgument *FromArgs, unsigned NumFromArgs,
SmallVectorImpl<TemplateArgument> &ToArgs) {
@@ -2011,6 +1999,12 @@ bool ASTNodeImporter::IsStructuralMatch(VarDecl *FromVar, VarDecl *ToVar,
}
bool ASTNodeImporter::IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToEnum) {
+ // Eliminate a potential failure point where we attempt to re-import
+ // something we're trying to import while completing ToEnum.
+ if (Decl *ToOrigin = Importer.GetOriginalDecl(ToEnum))
+ if (auto *ToOriginEnum = dyn_cast<EnumDecl>(ToOrigin))
+ ToEnum = ToOriginEnum;
+
StructuralEquivalenceContext Ctx(
Importer.getFromContext(), Importer.getToContext(),
Importer.getNonEquivalentDecls(), getStructuralEquivalenceKind(Importer));
@@ -2303,7 +2297,8 @@ ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
if (!FromUT->isIncompleteType() && !FoundUT->isIncompleteType())
return Importer.MapImported(D, FoundTypedef);
}
- // FIXME Handle redecl chain.
+ // FIXME Handle redecl chain. When you do that make consistent changes
+ // in ASTImporterLookupTable too.
break;
}
@@ -2492,6 +2487,8 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
}
if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
+ if (!hasSameVisibilityContext(FoundEnum, D))
+ continue;
if (IsStructuralMatch(D, FoundEnum))
return Importer.MapImported(D, FoundEnum);
}
@@ -2500,7 +2497,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
}
if (!ConflictingDecls.empty()) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
+ Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
@@ -2548,26 +2545,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Decl::FOK_None;
}
- // If this record has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- TagDecl *Definition = D->getDefinition();
- if (Definition && Definition != D &&
- // Friend template declaration must be imported on its own.
- !IsFriendTemplate &&
- // In contrast to a normal CXXRecordDecl, the implicit
- // CXXRecordDecl of ClassTemplateSpecializationDecl is its redeclaration.
- // The definition of the implicit CXXRecordDecl in this case is the
- // ClassTemplateSpecializationDecl itself. Thus, we start with an extra
- // condition in order to be able to import the implict Decl.
- !D->isImplicit()) {
- ExpectedDecl ImportedDefOrErr = import(Definition);
- if (!ImportedDefOrErr)
- return ImportedDefOrErr.takeError();
-
- return Importer.MapImported(D, *ImportedDefOrErr);
- }
-
// Import the major distinguishing characteristics of this record.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -2596,7 +2573,8 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
auto FoundDecls =
Importer.findDeclsInToCtx(DC, SearchName);
if (!FoundDecls.empty()) {
- // We're going to have to compare D against potentially conflicting Decls, so complete it.
+ // We're going to have to compare D against potentially conflicting Decls,
+ // so complete it.
if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
D->getASTContext().getExternalSource()->CompleteType(D);
}
@@ -2625,6 +2603,9 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
if (!IsStructuralMatch(D, FoundRecord, false))
continue;
+ if (!hasSameVisibilityContext(FoundRecord, D))
+ continue;
+
if (IsStructuralMatch(D, FoundRecord)) {
RecordDecl *FoundDef = FoundRecord->getDefinition();
if (D->isThisDeclarationADefinition() && FoundDef) {
@@ -2651,7 +2632,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
} // for
if (!ConflictingDecls.empty() && SearchName) {
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
+ Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
@@ -2848,6 +2829,22 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
return ToEnumerator;
}
+Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD,
+ DeclaratorDecl *ToD) {
+ unsigned int Num = FromD->getNumTemplateParameterLists();
+ if (Num == 0)
+ return Error::success();
+ SmallVector<TemplateParameterList *, 2> ToTPLists(Num);
+ for (unsigned int I = 0; I < Num; ++I)
+ if (Expected<TemplateParameterList *> ToTPListOrErr =
+ import(FromD->getTemplateParameterList(I)))
+ ToTPLists[I] = *ToTPListOrErr;
+ else
+ return ToTPListOrErr.takeError();
+ ToD->setTemplateParameterListsInfo(Importer.ToContext, ToTPLists);
+ return Error::success();
+}
+
Error ASTNodeImporter::ImportTemplateInformation(
FunctionDecl *FromFD, FunctionDecl *ToFD) {
switch (FromFD->getTemplatedKind()) {
@@ -2894,6 +2891,9 @@ Error ASTNodeImporter::ImportTemplateInformation(
if (!POIOrErr)
return POIOrErr.takeError();
+ if (Error Err = ImportTemplateParameterLists(FromFD, ToFD))
+ return Err;
+
TemplateSpecializationKind TSK = FTSInfo->getTemplateSpecializationKind();
ToFD->setFunctionTemplateSpecialization(
std::get<0>(*FunctionAndArgsOrErr), ToTAList, /* InsertPos= */ nullptr,
@@ -2945,6 +2945,30 @@ ASTNodeImporter::FindFunctionTemplateSpecialization(FunctionDecl *FromFD) {
return FoundSpec;
}
+Error ASTNodeImporter::ImportFunctionDeclBody(FunctionDecl *FromFD,
+ FunctionDecl *ToFD) {
+ if (Stmt *FromBody = FromFD->getBody()) {
+ if (ExpectedStmt ToBodyOrErr = import(FromBody))
+ ToFD->setBody(*ToBodyOrErr);
+ else
+ return ToBodyOrErr.takeError();
+ }
+ return Error::success();
+}
+
+template <typename T>
+bool ASTNodeImporter::hasSameVisibilityContext(T *Found, T *From) {
+ if (From->hasExternalFormalLinkage())
+ return Found->hasExternalFormalLinkage();
+ if (Importer.GetFromTU(Found) != From->getTranslationUnitDecl())
+ return false;
+ if (From->isInAnonymousNamespace())
+ return Found->isInAnonymousNamespace();
+ else
+ return !Found->isInAnonymousNamespace() &&
+ !Found->hasExternalFormalLinkage();
+}
+
ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
SmallVector<Decl *, 2> Redecls = getCanonicalForwardRedeclChain(D);
@@ -2968,7 +2992,7 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (ToD)
return ToD;
- const FunctionDecl *FoundByLookup = nullptr;
+ FunctionDecl *FoundByLookup = nullptr;
FunctionTemplateDecl *FromFT = D->getDescribedFunctionTemplate();
// If this is a function template specialization, then try to find the same
@@ -2982,8 +3006,8 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
if (!FoundFunctionOrErr)
return FoundFunctionOrErr.takeError();
if (FunctionDecl *FoundFunction = *FoundFunctionOrErr) {
- if (D->doesThisDeclarationHaveABody() && FoundFunction->hasBody())
- return Importer.MapImported(D, FoundFunction);
+ if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+ return Def;
FoundByLookup = FoundFunction;
}
}
@@ -2998,33 +3022,27 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
continue;
if (auto *FoundFunction = dyn_cast<FunctionDecl>(FoundDecl)) {
- if (FoundFunction->hasExternalFormalLinkage() &&
- D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundFunction)) {
- const FunctionDecl *Definition = nullptr;
- if (D->doesThisDeclarationHaveABody() &&
- FoundFunction->hasBody(Definition)) {
- return Importer.MapImported(
- D, const_cast<FunctionDecl *>(Definition));
- }
- FoundByLookup = FoundFunction;
- break;
- }
+ if (!hasSameVisibilityContext(FoundFunction, D))
+ continue;
- // FIXME: Check for overloading more carefully, e.g., by boosting
- // Sema::IsOverload out to the AST library.
+ if (IsStructuralMatch(D, FoundFunction)) {
+ if (Decl *Def = FindAndMapDefinition(D, FoundFunction))
+ return Def;
+ FoundByLookup = FoundFunction;
+ break;
+ }
+ // FIXME: Check for overloading more carefully, e.g., by boosting
+ // Sema::IsOverload out to the AST library.
- // Function overloading is okay in C++.
- if (Importer.getToContext().getLangOpts().CPlusPlus)
- continue;
+ // Function overloading is okay in C++.
+ if (Importer.getToContext().getLangOpts().CPlusPlus)
+ continue;
- // Complain about inconsistent function types.
- Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
+ // Complain about inconsistent function types.
+ Importer.ToDiag(Loc, diag::warn_odr_function_type_inconsistent)
<< Name << D->getType() << FoundFunction->getType();
- Importer.ToDiag(FoundFunction->getLocation(),
- diag::note_odr_value_here)
+ Importer.ToDiag(FoundFunction->getLocation(), diag::note_odr_value_here)
<< FoundFunction->getType();
- }
}
ConflictingDecls.push_back(FoundDecl);
@@ -3039,6 +3057,25 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
}
+ // We do not allow more than one in-class declaration of a function. This is
+ // because AST clients like VTableBuilder asserts on this. VTableBuilder
+ // assumes there is only one in-class declaration. Building a redecl
+ // chain would result in more than one in-class declaration for
+ // overrides (even if they are part of the same redecl chain inside the
+ // derived class.)
+ if (FoundByLookup) {
+ if (isa<CXXMethodDecl>(FoundByLookup)) {
+ if (D->getLexicalDeclContext() == D->getDeclContext()) {
+ if (!D->doesThisDeclarationHaveABody())
+ return Importer.MapImported(D, FoundByLookup);
+ else {
+ // Let's continue and build up the redecl chain in this case.
+ // FIXME Merge the functions into one decl.
+ }
+ }
+ }
+ }
+
DeclarationNameInfo NameInfo(Name, Loc);
// Import additional name location/type info.
if (Error Err = ImportDeclarationNameLoc(D->getNameInfo(), NameInfo))
@@ -3086,36 +3123,71 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Create the imported function.
FunctionDecl *ToFunction = nullptr;
if (auto *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
+ Expr *ExplicitExpr = nullptr;
+ if (FromConstructor->getExplicitSpecifier().getExpr()) {
+ auto Imp = importSeq(FromConstructor->getExplicitSpecifier().getExpr());
+ if (!Imp)
+ return Imp.takeError();
+ std::tie(ExplicitExpr) = *Imp;
+ }
if (GetImportedOrCreateDecl<CXXConstructorDecl>(
- ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
- ToInnerLocStart, NameInfo, T, TInfo,
- FromConstructor->isExplicit(),
- D->isInlineSpecified(), D->isImplicit(), D->isConstexpr()))
+ ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
+ ToInnerLocStart, NameInfo, T, TInfo,
+ ExplicitSpecifier(
+ ExplicitExpr,
+ FromConstructor->getExplicitSpecifier().getKind()),
+ D->isInlineSpecified(), D->isImplicit(), D->getConstexprKind()))
return ToFunction;
- } else if (isa<CXXDestructorDecl>(D)) {
+ } else if (CXXDestructorDecl *FromDtor = dyn_cast<CXXDestructorDecl>(D)) {
+
+ auto Imp =
+ importSeq(const_cast<FunctionDecl *>(FromDtor->getOperatorDelete()),
+ FromDtor->getOperatorDeleteThisArg());
+
+ if (!Imp)
+ return Imp.takeError();
+
+ FunctionDecl *ToOperatorDelete;
+ Expr *ToThisArg;
+ std::tie(ToOperatorDelete, ToThisArg) = *Imp;
+
if (GetImportedOrCreateDecl<CXXDestructorDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
D->isImplicit()))
return ToFunction;
+
+ CXXDestructorDecl *ToDtor = cast<CXXDestructorDecl>(ToFunction);
+
+ ToDtor->setOperatorDelete(ToOperatorDelete, ToThisArg);
} else if (CXXConversionDecl *FromConversion =
dyn_cast<CXXConversionDecl>(D)) {
+ Expr *ExplicitExpr = nullptr;
+ if (FromConversion->getExplicitSpecifier().getExpr()) {
+ auto Imp = importSeq(FromConversion->getExplicitSpecifier().getExpr());
+ if (!Imp)
+ return Imp.takeError();
+ std::tie(ExplicitExpr) = *Imp;
+ }
if (GetImportedOrCreateDecl<CXXConversionDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, D->isInlineSpecified(),
- FromConversion->isExplicit(), D->isConstexpr(), SourceLocation()))
+ ExplicitSpecifier(ExplicitExpr,
+ FromConversion->getExplicitSpecifier().getKind()),
+ D->getConstexprKind(), SourceLocation()))
return ToFunction;
} else if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
if (GetImportedOrCreateDecl<CXXMethodDecl>(
ToFunction, D, Importer.getToContext(), cast<CXXRecordDecl>(DC),
ToInnerLocStart, NameInfo, T, TInfo, Method->getStorageClass(),
- Method->isInlineSpecified(), D->isConstexpr(), SourceLocation()))
+ Method->isInlineSpecified(), D->getConstexprKind(),
+ SourceLocation()))
return ToFunction;
} else {
- if (GetImportedOrCreateDecl(ToFunction, D, Importer.getToContext(), DC,
- ToInnerLocStart, NameInfo, T, TInfo,
- D->getStorageClass(), D->isInlineSpecified(),
- D->hasWrittenPrototype(), D->isConstexpr()))
+ if (GetImportedOrCreateDecl(
+ ToFunction, D, Importer.getToContext(), DC, ToInnerLocStart,
+ NameInfo, T, TInfo, D->getStorageClass(), D->isInlineSpecified(),
+ D->hasWrittenPrototype(), D->getConstexprKind()))
return ToFunction;
}
@@ -3124,6 +3196,11 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
auto *Recent = const_cast<FunctionDecl *>(
FoundByLookup->getMostRecentDecl());
ToFunction->setPreviousDecl(Recent);
+ // FIXME Probably we should merge exception specifications. E.g. In the
+ // "To" context the existing function may have exception specification with
+ // noexcept-unevaluated, while the newly imported function may have an
+ // evaluated noexcept. A call to adjustExceptionSpec() on the imported
+ // decl and its redeclarations may be required.
}
// Import Ctor initializers.
@@ -3184,12 +3261,10 @@ ExpectedDecl ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
}
if (D->doesThisDeclarationHaveABody()) {
- if (Stmt *FromBody = D->getBody()) {
- if (ExpectedStmt ToBodyOrErr = import(FromBody))
- ToFunction->setBody(*ToBodyOrErr);
- else
- return ToBodyOrErr.takeError();
- }
+ Error Err = ImportFunctionDeclBody(D, ToFunction);
+
+ if (Err)
+ return std::move(Err);
}
// FIXME: Other bits to merge?
@@ -3292,7 +3367,7 @@ ExpectedDecl ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
}
// FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
@@ -3363,7 +3438,7 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
continue;
// FIXME: Why is this case not handled with calling HandleNameConflict?
- Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_field_type_inconsistent)
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
@@ -3394,9 +3469,6 @@ ExpectedDecl ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
// FIXME here we leak `NamedChain` which is allocated before
return ToIndirectField;
- for (const auto *Attr : D->attrs())
- ToIndirectField->addAttr(Importer.Import(Attr));
-
ToIndirectField->setAccess(D->getAccess());
ToIndirectField->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIndirectField);
@@ -3451,7 +3523,7 @@ ExpectedDecl ASTNodeImporter::VisitFriendDecl(FriendDecl *D) {
SmallVector<TemplateParameterList *, 1> ToTPLists(D->NumTPLists);
auto **FromTPLists = D->getTrailingObjects<TemplateParameterList *>();
for (unsigned I = 0; I < D->NumTPLists; I++) {
- if (auto ListOrErr = ImportTemplateParameterList(FromTPLists[I]))
+ if (auto ListOrErr = import(FromTPLists[I]))
ToTPLists[I] = *ListOrErr;
else
return ListOrErr.takeError();
@@ -3497,7 +3569,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
return FoundIvar;
}
- Importer.ToDiag(Loc, diag::err_odr_ivar_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_ivar_type_inconsistent)
<< Name << D->getType() << FoundIvar->getType();
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
@@ -3564,58 +3636,56 @@ ExpectedDecl ASTNodeImporter::VisitVarDecl(VarDecl *D) {
continue;
if (auto *FoundVar = dyn_cast<VarDecl>(FoundDecl)) {
- // We have found a variable that we may need to merge with. Check it.
- if (FoundVar->hasExternalFormalLinkage() &&
- D->hasExternalFormalLinkage()) {
- if (Importer.IsStructurallyEquivalent(D->getType(),
- FoundVar->getType())) {
-
- // The VarDecl in the "From" context has a definition, but in the
- // "To" context we already have a definition.
- VarDecl *FoundDef = FoundVar->getDefinition();
- if (D->isThisDeclarationADefinition() && FoundDef)
- // FIXME Check for ODR error if the two definitions have
- // different initializers?
- return Importer.MapImported(D, FoundDef);
-
- // The VarDecl in the "From" context has an initializer, but in the
- // "To" context we already have an initializer.
- const VarDecl *FoundDInit = nullptr;
- if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
- // FIXME Diagnose ODR error if the two initializers are different?
- return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
+ if (!hasSameVisibilityContext(FoundVar, D))
+ continue;
+ if (Importer.IsStructurallyEquivalent(D->getType(),
+ FoundVar->getType())) {
+
+ // The VarDecl in the "From" context has a definition, but in the
+ // "To" context we already have a definition.
+ VarDecl *FoundDef = FoundVar->getDefinition();
+ if (D->isThisDeclarationADefinition() && FoundDef)
+ // FIXME Check for ODR error if the two definitions have
+ // different initializers?
+ return Importer.MapImported(D, FoundDef);
+
+ // The VarDecl in the "From" context has an initializer, but in the
+ // "To" context we already have an initializer.
+ const VarDecl *FoundDInit = nullptr;
+ if (D->getInit() && FoundVar->getAnyInitializer(FoundDInit))
+ // FIXME Diagnose ODR error if the two initializers are different?
+ return Importer.MapImported(D, const_cast<VarDecl*>(FoundDInit));
+
+ FoundByLookup = FoundVar;
+ break;
+ }
+
+ const ArrayType *FoundArray
+ = Importer.getToContext().getAsArrayType(FoundVar->getType());
+ const ArrayType *TArray
+ = Importer.getToContext().getAsArrayType(D->getType());
+ if (FoundArray && TArray) {
+ if (isa<IncompleteArrayType>(FoundArray) &&
+ isa<ConstantArrayType>(TArray)) {
+ // Import the type.
+ if (auto TyOrErr = import(D->getType()))
+ FoundVar->setType(*TyOrErr);
+ else
+ return TyOrErr.takeError();
FoundByLookup = FoundVar;
break;
+ } else if (isa<IncompleteArrayType>(TArray) &&
+ isa<ConstantArrayType>(FoundArray)) {
+ FoundByLookup = FoundVar;
+ break;
}
-
- const ArrayType *FoundArray
- = Importer.getToContext().getAsArrayType(FoundVar->getType());
- const ArrayType *TArray
- = Importer.getToContext().getAsArrayType(D->getType());
- if (FoundArray && TArray) {
- if (isa<IncompleteArrayType>(FoundArray) &&
- isa<ConstantArrayType>(TArray)) {
- // Import the type.
- if (auto TyOrErr = import(D->getType()))
- FoundVar->setType(*TyOrErr);
- else
- return TyOrErr.takeError();
-
- FoundByLookup = FoundVar;
- break;
- } else if (isa<IncompleteArrayType>(TArray) &&
- isa<ConstantArrayType>(FoundArray)) {
- FoundByLookup = FoundVar;
- break;
- }
- }
-
- Importer.ToDiag(Loc, diag::err_odr_variable_type_inconsistent)
- << Name << D->getType() << FoundVar->getType();
- Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
- << FoundVar->getType();
}
+
+ Importer.ToDiag(Loc, diag::warn_odr_variable_type_inconsistent)
+ << Name << D->getType() << FoundVar->getType();
+ Importer.ToDiag(FoundVar->getLocation(), diag::note_odr_value_here)
+ << FoundVar->getType();
}
ConflictingDecls.push_back(FoundDecl);
@@ -3777,7 +3847,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check return types.
if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
FoundMethod->getReturnType())) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_result_type_inconsistent)
<< D->isInstanceMethod() << Name << D->getReturnType()
<< FoundMethod->getReturnType();
Importer.ToDiag(FoundMethod->getLocation(),
@@ -3789,7 +3859,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check the number of parameters.
if (D->param_size() != FoundMethod->param_size()) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_num_params_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_num_params_inconsistent)
<< D->isInstanceMethod() << Name
<< D->param_size() << FoundMethod->param_size();
Importer.ToDiag(FoundMethod->getLocation(),
@@ -3806,7 +3876,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
if (!Importer.IsStructurallyEquivalent((*P)->getType(),
(*FoundP)->getType())) {
Importer.FromDiag((*P)->getLocation(),
- diag::err_odr_objc_method_param_type_inconsistent)
+ diag::warn_odr_objc_method_param_type_inconsistent)
<< D->isInstanceMethod() << Name
<< (*P)->getType() << (*FoundP)->getType();
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
@@ -3819,7 +3889,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
// Check variadic/non-variadic.
// Check the number of parameters.
if (D->isVariadic() != FoundMethod->isVariadic()) {
- Importer.ToDiag(Loc, diag::err_odr_objc_method_variadic_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_method_variadic_inconsistent)
<< D->isInstanceMethod() << Name;
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
@@ -4364,7 +4434,7 @@ Error ASTNodeImporter::ImportDefinition(
if ((bool)FromSuper != (bool)ToSuper ||
(FromSuper && !declaresSameEntity(FromSuper, ToSuper))) {
Importer.ToDiag(To->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
+ diag::warn_odr_objc_superclass_inconsistent)
<< To->getDeclName();
if (ToSuper)
Importer.ToDiag(To->getSuperClassLoc(), diag::note_odr_objc_superclass)
@@ -4633,7 +4703,7 @@ ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
!declaresSameEntity(Super->getCanonicalDecl(),
Impl->getSuperClass()))) {
Importer.ToDiag(Impl->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
+ diag::warn_odr_objc_superclass_inconsistent)
<< Iface->getDeclName();
// FIXME: It would be nice to have the location of the superclass
// below.
@@ -4681,7 +4751,7 @@ ExpectedDecl ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Check property types.
if (!Importer.IsStructurallyEquivalent(D->getType(),
FoundProp->getType())) {
- Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
+ Importer.ToDiag(Loc, diag::warn_odr_objc_property_type_inconsistent)
<< Name << D->getType() << FoundProp->getType();
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
@@ -4788,7 +4858,7 @@ ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
// vs. @dynamic).
if (D->getPropertyImplementation() != ToImpl->getPropertyImplementation()) {
Importer.ToDiag(ToImpl->getLocation(),
- diag::err_odr_objc_property_impl_kind_inconsistent)
+ diag::warn_odr_objc_property_impl_kind_inconsistent)
<< Property->getDeclName()
<< (ToImpl->getPropertyImplementation()
== ObjCPropertyImplDecl::Dynamic);
@@ -4804,7 +4874,7 @@ ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize &&
Ivar != ToImpl->getPropertyIvarDecl()) {
Importer.ToDiag(ToImpl->getPropertyIvarDeclLoc(),
- diag::err_odr_objc_synthesize_ivar_inconsistent)
+ diag::warn_odr_objc_synthesize_ivar_inconsistent)
<< Property->getDeclName()
<< ToImpl->getPropertyIvarDecl()->getDeclName()
<< Ivar->getDeclName();
@@ -4888,8 +4958,7 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
return LocationOrErr.takeError();
// Import template parameters.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -4905,31 +4974,20 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
return ToD;
}
-// Returns the definition for a (forward) declaration of a ClassTemplateDecl, if
+// Returns the definition for a (forward) declaration of a TemplateDecl, if
// it has any definition in the redecl chain.
-static ClassTemplateDecl *getDefinition(ClassTemplateDecl *D) {
- CXXRecordDecl *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
+template <typename T> static auto getTemplateDefinition(T *D) -> T * {
+ assert(D->getTemplatedDecl() && "Should be called on templates only");
+ auto *ToTemplatedDef = D->getTemplatedDecl()->getDefinition();
if (!ToTemplatedDef)
return nullptr;
- ClassTemplateDecl *TemplateWithDef =
- ToTemplatedDef->getDescribedClassTemplate();
- return TemplateWithDef;
+ auto *TemplateWithDef = ToTemplatedDef->getDescribedTemplate();
+ return cast_or_null<T>(TemplateWithDef);
}
ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
bool IsFriend = D->getFriendObjectKind() != Decl::FOK_None;
- // If this template has a definition in the translation unit we're coming
- // from, but this particular declaration is not that definition, import the
- // definition and map to that.
- ClassTemplateDecl *Definition = getDefinition(D);
- if (Definition && Definition != D && !IsFriend) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
-
// Import the major distinguishing characteristics of this class template.
DeclContext *DC, *LexicalDC;
DeclarationName Name;
@@ -4956,7 +5014,8 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (FoundTemplate) {
if (IsStructuralMatch(D, FoundTemplate)) {
- ClassTemplateDecl *TemplateWithDef = getDefinition(FoundTemplate);
+ ClassTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
if (D->isThisDeclarationADefinition() && TemplateWithDef) {
return Importer.MapImported(D, TemplateWithDef);
}
@@ -4986,8 +5045,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
return std::move(Err);
// Create the class template declaration itself.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -5019,6 +5077,8 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// and this time the lookup finds the previous fwd friend class template.
// In this case we must set up the previous decl for the templated decl.
if (!ToTemplated->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
CXXRecordDecl *PrevTemplated =
FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
if (ToTemplated != PrevTemplated)
@@ -5041,17 +5101,6 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl *D) {
- // If this record has a definition in the translation unit we're coming from,
- // but this particular declaration is not that definition, import the
- // definition and map to that.
- TagDecl *Definition = D->getDefinition();
- if (Definition && Definition != D) {
- if (ExpectedDecl ImportedDefOrErr = import(Definition))
- return Importer.MapImported(D, *ImportedDefOrErr);
- else
- return ImportedDefOrErr.takeError();
- }
-
ClassTemplateDecl *ClassTemplate;
if (Error Err = importInto(ClassTemplate, D->getSpecializedTemplate()))
return std::move(Err);
@@ -5069,154 +5118,146 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
// Try to find an existing specialization with these template arguments.
void *InsertPos = nullptr;
- ClassTemplateSpecializationDecl *D2 = nullptr;
+ ClassTemplateSpecializationDecl *PrevDecl = nullptr;
ClassTemplatePartialSpecializationDecl *PartialSpec =
dyn_cast<ClassTemplatePartialSpecializationDecl>(D);
if (PartialSpec)
- D2 = ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
+ PrevDecl =
+ ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos);
else
- D2 = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
- ClassTemplateSpecializationDecl * const PrevDecl = D2;
- RecordDecl *FoundDef = D2 ? D2->getDefinition() : nullptr;
- if (FoundDef) {
- if (!D->isCompleteDefinition()) {
- // The "From" translation unit only had a forward declaration; call it
- // the same declaration.
- // TODO Handle the redecl chain properly!
- return Importer.MapImported(D, FoundDef);
- }
-
- if (IsStructuralMatch(D, FoundDef)) {
+ PrevDecl = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
+
+ if (PrevDecl) {
+ if (IsStructuralMatch(D, PrevDecl)) {
+ if (D->isThisDeclarationADefinition() && PrevDecl->getDefinition()) {
+ Importer.MapImported(D, PrevDecl->getDefinition());
+ // Import those default field initializers which have been
+ // instantiated in the "From" context, but not in the "To" context.
+ for (auto *FromField : D->fields()) {
+ auto ToOrErr = import(FromField);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ }
- Importer.MapImported(D, FoundDef);
+ // 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)
+ return ToOrErr.takeError();
+ }
- // 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());
+ // TODO Import instantiated default arguments.
+ // TODO Import instantiated exception specifications.
+ //
+ // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint
+ // what else could be fused during an AST merge.
+ return PrevDecl;
}
+ } else { // ODR violation.
+ // FIXME HandleNameConflict
+ return make_error<ImportError>(ImportError::NameConflict);
+ }
+ }
- // Import those methods which have been instantiated in the
- // "From" context, but not in the "To" context.
- for (CXXMethodDecl *FromM : D->methods()) {
- auto ToOrErr = import(FromM);
- if (!ToOrErr)
- // FIXME: return the error?
- consumeError(ToOrErr.takeError());
- }
+ // Import the location of this declaration.
+ ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
+ ExpectedSLoc IdLocOrErr = import(D->getLocation());
+ if (!IdLocOrErr)
+ return IdLocOrErr.takeError();
- // TODO Import instantiated default arguments.
- // TODO Import instantiated exception specifications.
- //
- // Generally, ASTCommon.h/DeclUpdateKind enum gives a very good hint what
- // else could be fused during an AST merge.
+ // Create the specialization.
+ ClassTemplateSpecializationDecl *D2 = nullptr;
+ if (PartialSpec) {
+ // Import TemplateArgumentListInfo.
+ TemplateArgumentListInfo ToTAInfo;
+ const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
+ if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
+ return std::move(Err);
- return FoundDef;
- }
- } else { // We either couldn't find any previous specialization in the "To"
- // context, or we found one but without definition. Let's create a
- // new specialization and register that at the class template.
+ QualType CanonInjType;
+ if (Error Err = importInto(
+ CanonInjType, PartialSpec->getInjectedSpecializationType()))
+ return std::move(Err);
+ CanonInjType = CanonInjType.getCanonicalType();
+
+ auto ToTPListOrErr = import(PartialSpec->getTemplateParameters());
+ if (!ToTPListOrErr)
+ return ToTPListOrErr.takeError();
+
+ if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
+ llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
+ ToTAInfo, CanonInjType,
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
+ return D2;
- // Import the location of this declaration.
- ExpectedSLoc BeginLocOrErr = import(D->getBeginLoc());
- if (!BeginLocOrErr)
- return BeginLocOrErr.takeError();
- ExpectedSLoc IdLocOrErr = import(D->getLocation());
- if (!IdLocOrErr)
- return IdLocOrErr.takeError();
-
- if (PartialSpec) {
- // Import TemplateArgumentListInfo.
- TemplateArgumentListInfo ToTAInfo;
- const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
- if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
- return std::move(Err);
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
+ // Add this partial specialization to the class template.
+ ClassTemplate->AddPartialSpecialization(
+ cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
- QualType CanonInjType;
- if (Error Err = importInto(
- CanonInjType, PartialSpec->getInjectedSpecializationType()))
- return std::move(Err);
- CanonInjType = CanonInjType.getCanonicalType();
+ } else { // Not a partial specialization.
+ if (GetImportedOrCreateDecl(
+ D2, D, Importer.getToContext(), D->getTagKind(), DC,
+ *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
+ PrevDecl))
+ return D2;
- auto ToTPListOrErr = ImportTemplateParameterList(
- PartialSpec->getTemplateParameters());
- if (!ToTPListOrErr)
- return ToTPListOrErr.takeError();
+ // Update InsertPos, because preceding import calls may have invalidated
+ // it by adding new specializations.
+ if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
+ // Add this specialization to the class template.
+ ClassTemplate->AddSpecialization(D2, InsertPos);
+ }
- if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, ClassTemplate,
- llvm::makeArrayRef(TemplateArgs.data(), TemplateArgs.size()),
- ToTAInfo, CanonInjType,
- cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
- return D2;
+ D2->setSpecializationKind(D->getSpecializationKind());
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findPartialSpecialization(TemplateArgs, InsertPos))
- // Add this partial specialization to the class template.
- ClassTemplate->AddPartialSpecialization(
- cast<ClassTemplatePartialSpecializationDecl>(D2), InsertPos);
+ // Set the context of this specialization/instantiation.
+ D2->setLexicalDeclContext(LexicalDC);
- } else { // Not a partial specialization.
- if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
- PrevDecl))
- return D2;
+ // Add to the DC only if it was an explicit specialization/instantiation.
+ if (D2->isExplicitInstantiationOrSpecialization()) {
+ LexicalDC->addDeclInternal(D2);
+ }
- // Update InsertPos, because preceding import calls may have invalidated
- // it by adding new specializations.
- if (!ClassTemplate->findSpecialization(TemplateArgs, InsertPos))
- // Add this specialization to the class template.
- ClassTemplate->AddSpecialization(D2, InsertPos);
- }
+ // Import the qualifier, if any.
+ if (auto LocOrErr = import(D->getQualifierLoc()))
+ D2->setQualifierInfo(*LocOrErr);
+ else
+ return LocOrErr.takeError();
- D2->setSpecializationKind(D->getSpecializationKind());
+ if (auto *TSI = D->getTypeAsWritten()) {
+ if (auto TInfoOrErr = import(TSI))
+ D2->setTypeAsWritten(*TInfoOrErr);
+ else
+ return TInfoOrErr.takeError();
- // Import the qualifier, if any.
- if (auto LocOrErr = import(D->getQualifierLoc()))
- D2->setQualifierInfo(*LocOrErr);
+ if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
+ D2->setTemplateKeywordLoc(*LocOrErr);
else
return LocOrErr.takeError();
- if (auto *TSI = D->getTypeAsWritten()) {
- if (auto TInfoOrErr = import(TSI))
- D2->setTypeAsWritten(*TInfoOrErr);
- else
- return TInfoOrErr.takeError();
-
- if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
- D2->setTemplateKeywordLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
-
- if (auto LocOrErr = import(D->getExternLoc()))
- D2->setExternLoc(*LocOrErr);
- else
- return LocOrErr.takeError();
- }
-
- if (D->getPointOfInstantiation().isValid()) {
- if (auto POIOrErr = import(D->getPointOfInstantiation()))
- D2->setPointOfInstantiation(*POIOrErr);
- else
- return POIOrErr.takeError();
- }
+ if (auto LocOrErr = import(D->getExternLoc()))
+ D2->setExternLoc(*LocOrErr);
+ else
+ return LocOrErr.takeError();
+ }
- D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
+ if (D->getPointOfInstantiation().isValid()) {
+ if (auto POIOrErr = import(D->getPointOfInstantiation()))
+ D2->setPointOfInstantiation(*POIOrErr);
+ else
+ return POIOrErr.takeError();
+ }
- // Set the context of this specialization/instantiation.
- D2->setLexicalDeclContext(LexicalDC);
+ D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind());
- // Add to the DC only if it was an explicit specialization/instantiation.
- if (D2->isExplicitInstantiationOrSpecialization()) {
- LexicalDC->addDeclInternal(D2);
- }
- }
if (D->isCompleteDefinition())
if (Error Err = ImportDefinition(D, D2))
return std::move(Err);
@@ -5296,8 +5337,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
return std::move(Err);
// Create the variable template declaration itself.
- auto TemplateParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto TemplateParamsOrErr = import(D->getTemplateParameters());
if (!TemplateParamsOrErr)
return TemplateParamsOrErr.takeError();
@@ -5333,7 +5373,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
return ImportedDefOrErr.takeError();
}
- VarTemplateDecl *VarTemplate;
+ VarTemplateDecl *VarTemplate = nullptr;
if (Error Err = importInto(VarTemplate, D->getSpecializedTemplate()))
return std::move(Err);
@@ -5402,8 +5442,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
*FromTAArgsAsWritten, ArgInfos))
return std::move(Err);
- auto ToTPListOrErr = ImportTemplateParameterList(
- FromPartial->getTemplateParameters());
+ auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
if (!ToTPListOrErr)
return ToTPListOrErr.takeError();
@@ -5481,32 +5520,37 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
if (ToD)
return ToD;
+ const FunctionTemplateDecl *FoundByLookup = nullptr;
+
// Try to find a function in our own ("to") context with the same name, same
// type, and in the same context as the function we're importing.
+ // FIXME Split this into a separate function.
if (!LexicalDC->isFunctionOrMethod()) {
- unsigned IDNS = Decl::IDNS_Ordinary;
+ unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_OrdinaryFriend;
auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
if (!FoundDecl->isInIdentifierNamespace(IDNS))
continue;
- if (auto *FoundFunction =
- dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
- if (FoundFunction->hasExternalFormalLinkage() &&
+ if (auto *FoundTemplate = dyn_cast<FunctionTemplateDecl>(FoundDecl)) {
+ if (FoundTemplate->hasExternalFormalLinkage() &&
D->hasExternalFormalLinkage()) {
- if (IsStructuralMatch(D, FoundFunction)) {
- Importer.MapImported(D, FoundFunction);
- // FIXME: Actually try to merge the body and other attributes.
- return FoundFunction;
+ if (IsStructuralMatch(D, FoundTemplate)) {
+ FunctionTemplateDecl *TemplateWithDef =
+ getTemplateDefinition(FoundTemplate);
+ if (D->isThisDeclarationADefinition() && TemplateWithDef) {
+ return Importer.MapImported(D, TemplateWithDef);
+ }
+ FoundByLookup = FoundTemplate;
+ break;
}
+ // TODO: handle conflicting names
}
}
- // TODO: handle conflicting names
}
}
- auto ParamsOrErr = ImportTemplateParameterList(
- D->getTemplateParameters());
+ auto ParamsOrErr = import(D->getTemplateParameters());
if (!ParamsOrErr)
return ParamsOrErr.takeError();
@@ -5520,10 +5564,25 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
return ToFunc;
TemplatedFD->setDescribedFunctionTemplate(ToFunc);
+
ToFunc->setAccess(D->getAccess());
ToFunc->setLexicalDeclContext(LexicalDC);
-
LexicalDC->addDeclInternal(ToFunc);
+
+ if (FoundByLookup) {
+ auto *Recent =
+ const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl());
+ if (!TemplatedFD->getPreviousDecl()) {
+ assert(FoundByLookup->getTemplatedDecl() &&
+ "Found decl must have its templated decl set");
+ auto *PrevTemplated =
+ FoundByLookup->getTemplatedDecl()->getMostRecentDecl();
+ if (TemplatedFD != PrevTemplated)
+ TemplatedFD->setPreviousDecl(PrevTemplated);
+ }
+ ToFunc->setPreviousDecl(Recent);
+ }
+
return ToFunc;
}
@@ -5539,6 +5598,8 @@ ExpectedStmt ASTNodeImporter::VisitStmt(Stmt *S) {
ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
+ if (Importer.returnWithErrorInTest())
+ return make_error<ImportError>(ImportError::UnsupportedConstruct);
SmallVector<IdentifierInfo *, 4> Names;
for (unsigned I = 0, E = S->getNumOutputs(); I != E; I++) {
IdentifierInfo *ToII = Importer.Import(S->getOutputIdentifier(I));
@@ -5578,12 +5639,17 @@ ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
return InputOrErr.takeError();
}
- SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs());
+ SmallVector<Expr *, 4> Exprs(S->getNumOutputs() + S->getNumInputs() +
+ S->getNumLabels());
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);
+
if (Error Err = ImportArrayChecked(
- S->inputs(), Exprs.begin() + S->getNumOutputs()))
+ S->labels(), Exprs.begin() + S->getNumOutputs() + S->getNumInputs()))
return std::move(Err);
ExpectedSLoc AsmLocOrErr = import(S->getAsmLoc());
@@ -5609,6 +5675,7 @@ ExpectedStmt ASTNodeImporter::VisitGCCAsmStmt(GCCAsmStmt *S) {
*AsmStrOrErr,
S->getNumClobbers(),
Clobbers.data(),
+ S->getNumLabels(),
*RParenLocOrErr);
}
@@ -6079,6 +6146,33 @@ ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) {
E->isMicrosoftABI());
}
+ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) {
+ auto Imp = importSeq(E->getCond(), E->getLHS(), E->getRHS(),
+ E->getBuiltinLoc(), E->getRParenLoc(), E->getType());
+ if (!Imp)
+ return Imp.takeError();
+
+ Expr *ToCond;
+ Expr *ToLHS;
+ Expr *ToRHS;
+ SourceLocation ToBuiltinLoc, ToRParenLoc;
+ QualType ToType;
+ std::tie(ToCond, ToLHS, ToRHS, ToBuiltinLoc, ToRParenLoc, ToType) = *Imp;
+
+ ExprValueKind VK = E->getValueKind();
+ ExprObjectKind OK = E->getObjectKind();
+
+ bool TypeDependent = ToCond->isTypeDependent();
+ bool ValueDependent = ToCond->isValueDependent();
+
+ // The value of CondIsTrue only matters if the value is not
+ // condition-dependent.
+ bool CondIsTrue = !E->isConditionDependent() && E->isConditionTrue();
+
+ return new (Importer.getToContext())
+ ChooseExpr(ToBuiltinLoc, ToCond, ToLHS, ToRHS, ToType, VK, OK,
+ ToRParenLoc, CondIsTrue, TypeDependent, ValueDependent);
+}
ExpectedStmt ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) {
ExpectedType TypeOrErr = import(E->getType());
@@ -6141,7 +6235,7 @@ ExpectedStmt ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
auto *ToE = DeclRefExpr::Create(
Importer.getToContext(), ToQualifierLoc, ToTemplateKeywordLoc, ToDecl,
E->refersToEnclosingVariableOrCapture(), ToLocation, ToType,
- E->getValueKind(), ToFoundD, ToResInfo);
+ E->getValueKind(), ToFoundD, ToResInfo, E->isNonOdrUse());
if (E->hadMultipleCandidates())
ToE->setHadMultipleCandidates(true);
return ToE;
@@ -6327,6 +6421,13 @@ ExpectedStmt ASTNodeImporter::VisitConstantExpr(ConstantExpr *E) {
Expr *ToSubExpr;
std::tie(ToSubExpr) = *Imp;
+ // TODO : Handle APValue::ValueKind that require importing.
+ APValue::ValueKind Kind = E->getResultAPValueKind();
+ if (Kind == APValue::Int || Kind == APValue::Float ||
+ Kind == APValue::FixedPoint || Kind == APValue::ComplexFloat ||
+ Kind == APValue::ComplexInt)
+ return ConstantExpr::Create(Importer.getToContext(), ToSubExpr,
+ E->getAPValueResult());
return ConstantExpr::Create(Importer.getToContext(), ToSubExpr);
}
@@ -6763,8 +6864,12 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
if (!ToParamOrErr)
return ToParamOrErr.takeError();
+ auto UsedContextOrErr = Importer.ImportContext(E->getUsedContext());
+ if (!UsedContextOrErr)
+ return UsedContextOrErr.takeError();
+
return CXXDefaultArgExpr::Create(
- Importer.getToContext(), *ToUsedLocOrErr, *ToParamOrErr);
+ Importer.getToContext(), *ToUsedLocOrErr, *ToParamOrErr, *UsedContextOrErr);
}
ExpectedStmt
@@ -6898,7 +7003,8 @@ ExpectedStmt ASTNodeImporter::VisitCXXNewExpr(CXXNewExpr *E) {
FunctionDecl *ToOperatorNew, *ToOperatorDelete;
SourceRange ToTypeIdParens, ToSourceRange, ToDirectInitRange;
- Expr *ToArraySize, *ToInitializer;
+ Optional<Expr *> ToArraySize;
+ Expr *ToInitializer;
QualType ToType;
TypeSourceInfo *ToAllocatedTypeSourceInfo;
std::tie(
@@ -7051,15 +7157,20 @@ ExpectedStmt ASTNodeImporter::VisitMemberExpr(MemberExpr *E) {
DeclarationNameInfo ToMemberNameInfo(ToName, ToLoc);
+ TemplateArgumentListInfo ToTAInfo, *ResInfo = nullptr;
if (E->hasExplicitTemplateArgs()) {
- // FIXME: handle template arguments
- return make_error<ImportError>(ImportError::UnsupportedConstruct);
+ if (Error Err =
+ ImportTemplateArgumentListInfo(E->getLAngleLoc(), E->getRAngleLoc(),
+ E->template_arguments(), ToTAInfo))
+ return std::move(Err);
+ ResInfo = &ToTAInfo;
}
- return MemberExpr::Create(
- Importer.getToContext(), ToBase, E->isArrow(), ToOperatorLoc,
- ToQualifierLoc, ToTemplateKeywordLoc, ToMemberDecl, ToFoundDecl,
- ToMemberNameInfo, nullptr, ToType, E->getValueKind(), E->getObjectKind());
+ return MemberExpr::Create(Importer.getToContext(), ToBase, E->isArrow(),
+ ToOperatorLoc, ToQualifierLoc, ToTemplateKeywordLoc,
+ ToMemberDecl, ToFoundDecl, ToMemberNameInfo,
+ ResInfo, ToType, E->getValueKind(),
+ E->getObjectKind(), E->isNonOdrUse());
}
ExpectedStmt
@@ -7334,23 +7445,10 @@ ExpectedStmt ASTNodeImporter::VisitLambdaExpr(LambdaExpr *E) {
return ToClassOrErr.takeError();
CXXRecordDecl *ToClass = *ToClassOrErr;
- // NOTE: lambda classes are created with BeingDefined flag set up.
- // It means that ImportDefinition doesn't work for them and we should fill it
- // manually.
- if (ToClass->isBeingDefined()) {
- for (auto FromField : FromClass->fields()) {
- auto ToFieldOrErr = import(FromField);
- if (!ToFieldOrErr)
- return ToFieldOrErr.takeError();
- }
- }
-
auto ToCallOpOrErr = import(E->getCallOperator());
if (!ToCallOpOrErr)
return ToCallOpOrErr.takeError();
- ToClass->completeDefinition();
-
SmallVector<LambdaCapture, 8> ToCaptures;
ToCaptures.reserve(E->capture_size());
for (const auto &FromCapture : E->captures()) {
@@ -7486,8 +7584,12 @@ ExpectedStmt ASTNodeImporter::VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
if (!ToFieldOrErr)
return ToFieldOrErr.takeError();
+ auto UsedContextOrErr = Importer.ImportContext(E->getUsedContext());
+ if (!UsedContextOrErr)
+ return UsedContextOrErr.takeError();
+
return CXXDefaultInitExpr::Create(
- Importer.getToContext(), *ToBeginLocOrErr, *ToFieldOrErr);
+ Importer.getToContext(), *ToBeginLocOrErr, *ToFieldOrErr, *UsedContextOrErr);
}
ExpectedStmt ASTNodeImporter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) {
@@ -7613,24 +7715,22 @@ void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
ASTImporter::ASTImporter(ASTContext &ToContext, FileManager &ToFileManager,
ASTContext &FromContext, FileManager &FromFileManager,
bool MinimalImport,
- ASTImporterLookupTable *LookupTable)
- : LookupTable(LookupTable), ToContext(ToContext), FromContext(FromContext),
+ std::shared_ptr<ASTImporterSharedState> SharedState)
+ : SharedState(SharedState), ToContext(ToContext), FromContext(FromContext),
ToFileManager(ToFileManager), FromFileManager(FromFileManager),
Minimal(MinimalImport) {
+ // Create a default state without the lookup table: LLDB case.
+ if (!SharedState) {
+ this->SharedState = std::make_shared<ASTImporterSharedState>();
+ }
+
ImportedDecls[FromContext.getTranslationUnitDecl()] =
ToContext.getTranslationUnitDecl();
}
ASTImporter::~ASTImporter() = default;
-Expected<QualType> ASTImporter::Import_New(QualType FromT) {
- QualType ToT = Import(FromT);
- if (ToT.isNull() && !FromT.isNull())
- return make_error<ImportError>();
- return ToT;
-}
-
Optional<unsigned> ASTImporter::getFieldIndex(Decl *F) {
assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
"Try to get field index for non-field.");
@@ -7663,28 +7763,46 @@ ASTImporter::findDeclsInToCtx(DeclContext *DC, DeclarationName Name) {
// then the enum constant 'A' and the variable 'A' violates ODR.
// We can diagnose this only if we search in the redecl context.
DeclContext *ReDC = DC->getRedeclContext();
- if (LookupTable) {
+ if (SharedState->getLookupTable()) {
ASTImporterLookupTable::LookupResult LookupResult =
- LookupTable->lookup(ReDC, Name);
+ SharedState->getLookupTable()->lookup(ReDC, Name);
return FoundDeclsTy(LookupResult.begin(), LookupResult.end());
} else {
- // FIXME Can we remove this kind of lookup?
- // Or lldb really needs this C/C++ lookup?
- FoundDeclsTy Result;
- ReDC->localUncachedLookup(Name, Result);
+ DeclContext::lookup_result NoloadLookupResult = ReDC->noload_lookup(Name);
+ FoundDeclsTy Result(NoloadLookupResult.begin(), NoloadLookupResult.end());
+ // We must search by the slow case of localUncachedLookup because that is
+ // working even if there is no LookupPtr for the DC. We could use
+ // DC::buildLookup() to create the LookupPtr, but that would load external
+ // decls again, we must avoid that case.
+ // Also, even if we had the LookupPtr, we must find Decls which are not
+ // in the LookupPtr, so we need the slow case.
+ // These cases are handled in ASTImporterLookupTable, but we cannot use
+ // that with LLDB since that traverses through the AST which initiates the
+ // load of external decls again via DC::decls(). And again, we must avoid
+ // loading external decls during the import.
+ if (Result.empty())
+ ReDC->localUncachedLookup(Name, Result);
return Result;
}
}
void ASTImporter::AddToLookupTable(Decl *ToD) {
- if (LookupTable)
- if (auto *ToND = dyn_cast<NamedDecl>(ToD))
- LookupTable->add(ToND);
+ SharedState->addDeclToLookup(ToD);
+}
+
+Expected<Decl *> ASTImporter::ImportImpl(Decl *FromD) {
+ // Import the decl using ASTNodeImporter.
+ ASTNodeImporter Importer(*this);
+ return Importer.Visit(FromD);
+}
+
+void ASTImporter::RegisterImportedDecl(Decl *FromD, Decl *ToD) {
+ MapImported(FromD, ToD);
}
-QualType ASTImporter::Import(QualType FromT) {
+Expected<QualType> ASTImporter::Import(QualType FromT) {
if (FromT.isNull())
- return {};
+ return QualType{};
const Type *FromTy = FromT.getTypePtr();
@@ -7697,10 +7815,8 @@ QualType ASTImporter::Import(QualType FromT) {
// Import the type
ASTNodeImporter Importer(*this);
ExpectedType ToTOrErr = Importer.Visit(FromTy);
- if (!ToTOrErr) {
- llvm::consumeError(ToTOrErr.takeError());
- return {};
- }
+ if (!ToTOrErr)
+ return ToTOrErr.takeError();
// Record the imported type.
ImportedTypes[FromTy] = (*ToTOrErr).getTypePtr();
@@ -7708,33 +7824,29 @@ QualType ASTImporter::Import(QualType FromT) {
return ToContext.getQualifiedType(*ToTOrErr, FromT.getLocalQualifiers());
}
-Expected<TypeSourceInfo *> ASTImporter::Import_New(TypeSourceInfo *FromTSI) {
- TypeSourceInfo *ToTSI = Import(FromTSI);
- if (!ToTSI && FromTSI)
- return llvm::make_error<ImportError>();
- return ToTSI;
-}
-TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
+Expected<TypeSourceInfo *> ASTImporter::Import(TypeSourceInfo *FromTSI) {
if (!FromTSI)
return FromTSI;
// FIXME: For now we just create a "trivial" type source info based
// on the type and a single location. Implement a real version of this.
- QualType T = Import(FromTSI->getType());
- if (T.isNull())
- return nullptr;
+ ExpectedType TOrErr = Import(FromTSI->getType());
+ if (!TOrErr)
+ return TOrErr.takeError();
+ ExpectedSLoc BeginLocOrErr = Import(FromTSI->getTypeLoc().getBeginLoc());
+ if (!BeginLocOrErr)
+ return BeginLocOrErr.takeError();
- return ToContext.getTrivialTypeSourceInfo(
- T, Import(FromTSI->getTypeLoc().getBeginLoc()));
+ return ToContext.getTrivialTypeSourceInfo(*TOrErr, *BeginLocOrErr);
}
-Expected<Attr *> ASTImporter::Import_New(const Attr *FromAttr) {
- return Import(FromAttr);
-}
-Attr *ASTImporter::Import(const Attr *FromAttr) {
+Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
Attr *ToAttr = FromAttr->clone(ToContext);
- // NOTE: Import of SourceRange may fail.
- ToAttr->setRange(Import(FromAttr->getRange()));
+ if (auto ToRangeOrErr = Import(FromAttr->getRange()))
+ ToAttr->setRange(*ToRangeOrErr);
+ else
+ return ToRangeOrErr.takeError();
+
return ToAttr;
}
@@ -7746,53 +7858,147 @@ Decl *ASTImporter::GetAlreadyImportedOrNull(const Decl *FromD) const {
return nullptr;
}
-Expected<Decl *> ASTImporter::Import_New(Decl *FromD) {
- Decl *ToD = Import(FromD);
- if (!ToD && FromD)
- return llvm::make_error<ImportError>();
- return ToD;
+TranslationUnitDecl *ASTImporter::GetFromTU(Decl *ToD) {
+ auto FromDPos = ImportedFromDecls.find(ToD);
+ if (FromDPos == ImportedFromDecls.end())
+ return nullptr;
+ return FromDPos->second->getTranslationUnitDecl();
}
-Decl *ASTImporter::Import(Decl *FromD) {
+
+Expected<Decl *> ASTImporter::Import(Decl *FromD) {
if (!FromD)
return nullptr;
- ASTNodeImporter Importer(*this);
+ // Push FromD to the stack, and remove that when we return.
+ ImportPath.push(FromD);
+ auto ImportPathBuilder =
+ llvm::make_scope_exit([this]() { ImportPath.pop(); });
+
+ // Check whether there was a previous failed import.
+ // If yes return the existing error.
+ if (auto Error = getImportDeclErrorIfAny(FromD))
+ return make_error<ImportError>(*Error);
// Check whether we've already imported this declaration.
Decl *ToD = GetAlreadyImportedOrNull(FromD);
if (ToD) {
+ // Already imported (possibly from another TU) and with an error.
+ if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
+ setImportDeclError(FromD, *Error);
+ return make_error<ImportError>(*Error);
+ }
+
// If FromD has some updated flags after last import, apply it
updateFlags(FromD, ToD);
+ // If we encounter a cycle during an import then we save the relevant part
+ // of the import path associated to the Decl.
+ if (ImportPath.hasCycleAtBack())
+ SavedImportPaths[FromD].push_back(ImportPath.copyCycleAtBack());
return ToD;
}
- // Import the type.
- ExpectedDecl ToDOrErr = Importer.Visit(FromD);
+ // Import the declaration.
+ ExpectedDecl ToDOrErr = ImportImpl(FromD);
if (!ToDOrErr) {
- llvm::consumeError(ToDOrErr.takeError());
- return nullptr;
+ // Failed to import.
+
+ auto Pos = ImportedDecls.find(FromD);
+ if (Pos != ImportedDecls.end()) {
+ // Import failed after the object was created.
+ // Remove all references to it.
+ auto *ToD = Pos->second;
+ ImportedDecls.erase(Pos);
+
+ // ImportedDecls and ImportedFromDecls are not symmetric. It may happen
+ // (e.g. with namespaces) that several decls from the 'from' context are
+ // mapped to the same decl in the 'to' context. If we removed entries
+ // from the LookupTable here then we may end up removing them multiple
+ // times.
+
+ // The Lookuptable contains decls only which are in the 'to' context.
+ // Remove from the Lookuptable only if it is *imported* into the 'to'
+ // context (and do not remove it if it was added during the initial
+ // traverse of the 'to' context).
+ auto PosF = ImportedFromDecls.find(ToD);
+ if (PosF != ImportedFromDecls.end()) {
+ SharedState->removeDeclFromLookup(ToD);
+ ImportedFromDecls.erase(PosF);
+ }
+
+ // FIXME: AST may contain remaining references to the failed object.
+ // However, the ImportDeclErrors in the shared state contains all the
+ // failed objects together with their error.
+ }
+
+ // Error encountered for the first time.
+ // After takeError the error is not usable any more in ToDOrErr.
+ // Get a copy of the error object (any more simple solution for this?).
+ ImportError ErrOut;
+ handleAllErrors(ToDOrErr.takeError(),
+ [&ErrOut](const ImportError &E) { ErrOut = E; });
+ setImportDeclError(FromD, ErrOut);
+ // Set the error for the mapped to Decl, which is in the "to" context.
+ if (Pos != ImportedDecls.end())
+ SharedState->setImportDeclError(Pos->second, ErrOut);
+
+ // Set the error for all nodes which have been created before we
+ // recognized the error.
+ for (const auto &Path : SavedImportPaths[FromD])
+ for (Decl *FromDi : Path) {
+ setImportDeclError(FromDi, ErrOut);
+ //FIXME Should we remove these Decls from ImportedDecls?
+ // Set the error for the mapped to Decl, which is in the "to" context.
+ auto Ii = ImportedDecls.find(FromDi);
+ if (Ii != ImportedDecls.end())
+ SharedState->setImportDeclError(Ii->second, ErrOut);
+ // FIXME Should we remove these Decls from the LookupTable,
+ // and from ImportedFromDecls?
+ }
+ SavedImportPaths[FromD].clear();
+
+ // Do not return ToDOrErr, error was taken out of it.
+ return make_error<ImportError>(ErrOut);
}
+
ToD = *ToDOrErr;
- // Once the decl is connected to the existing declarations, i.e. when the
- // redecl chain is properly set then we populate the lookup again.
- // This way the primary context will be able to find all decls.
- AddToLookupTable(ToD);
+ // FIXME: Handle the "already imported with error" case. We can get here
+ // nullptr only if GetImportedOrCreateDecl returned nullptr (after a
+ // previously failed create was requested).
+ // Later GetImportedOrCreateDecl can be updated to return the error.
+ if (!ToD) {
+ auto Err = getImportDeclErrorIfAny(FromD);
+ assert(Err);
+ return make_error<ImportError>(*Err);
+ }
+
+ // We could import from the current TU without error. But previously we
+ // already had imported a Decl as `ToD` from another TU (with another
+ // ASTImporter object) and with an error.
+ if (auto Error = SharedState->getImportDeclErrorIfAny(ToD)) {
+ setImportDeclError(FromD, *Error);
+ return make_error<ImportError>(*Error);
+ }
+
+ // Make sure that ImportImpl registered the imported decl.
+ assert(ImportedDecls.count(FromD) != 0 && "Missing call to MapImported?");
// Notify subclasses.
Imported(FromD, ToD);
updateFlags(FromD, ToD);
- return ToD;
+ SavedImportPaths[FromD].clear();
+ return ToDOrErr;
}
Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
if (!FromDC)
return FromDC;
- auto *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
- if (!ToDC)
- return nullptr;
+ ExpectedDecl ToDCOrErr = Import(cast<Decl>(FromDC));
+ if (!ToDCOrErr)
+ return ToDCOrErr.takeError();
+ auto *ToDC = cast<DeclContext>(*ToDCOrErr);
// When we're using a record/enum/Objective-C class/protocol as a context, we
// need it to have a definition.
@@ -7845,30 +8051,18 @@ Expected<DeclContext *> ASTImporter::ImportContext(DeclContext *FromDC) {
return ToDC;
}
-Expected<Expr *> ASTImporter::Import_New(Expr *FromE) {
- Expr *ToE = Import(FromE);
- if (!ToE && FromE)
- return llvm::make_error<ImportError>();
- return ToE;
-}
-Expr *ASTImporter::Import(Expr *FromE) {
- if (!FromE)
- return nullptr;
-
- return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
+Expected<Expr *> ASTImporter::Import(Expr *FromE) {
+ if (ExpectedStmt ToSOrErr = Import(cast_or_null<Stmt>(FromE)))
+ return cast_or_null<Expr>(*ToSOrErr);
+ else
+ return ToSOrErr.takeError();
}
-Expected<Stmt *> ASTImporter::Import_New(Stmt *FromS) {
- Stmt *ToS = Import(FromS);
- if (!ToS && FromS)
- return llvm::make_error<ImportError>();
- return ToS;
-}
-Stmt *ASTImporter::Import(Stmt *FromS) {
+Expected<Stmt *> ASTImporter::Import(Stmt *FromS) {
if (!FromS)
return nullptr;
- // Check whether we've already imported this declaration.
+ // Check whether we've already imported this statement.
llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
if (Pos != ImportedStmts.end())
return Pos->second;
@@ -7876,10 +8070,8 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
// Import the statement.
ASTNodeImporter Importer(*this);
ExpectedStmt ToSOrErr = Importer.Visit(FromS);
- if (!ToSOrErr) {
- llvm::consumeError(ToSOrErr.takeError());
- return nullptr;
- }
+ if (!ToSOrErr)
+ return ToSOrErr;
if (auto *ToE = dyn_cast<Expr>(*ToSOrErr)) {
auto *FromE = cast<Expr>(FromS);
@@ -7894,77 +8086,68 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
FromE->containsUnexpandedParameterPack());
}
- // Record the imported declaration.
+ // Record the imported statement object.
ImportedStmts[FromS] = *ToSOrErr;
- return *ToSOrErr;
+ return ToSOrErr;
}
Expected<NestedNameSpecifier *>
-ASTImporter::Import_New(NestedNameSpecifier *FromNNS) {
- NestedNameSpecifier *ToNNS = Import(FromNNS);
- if (!ToNNS && FromNNS)
- return llvm::make_error<ImportError>();
- return ToNNS;
-}
-NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
+ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (!FromNNS)
return nullptr;
- NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
+ NestedNameSpecifier *Prefix = nullptr;
+ if (Error Err = importInto(Prefix, FromNNS->getPrefix()))
+ return std::move(Err);
switch (FromNNS->getKind()) {
case NestedNameSpecifier::Identifier:
- if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
- return NestedNameSpecifier::Create(ToContext, prefix, II);
- }
- return nullptr;
+ assert(FromNNS->getAsIdentifier() && "NNS should contain identifier.");
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ Import(FromNNS->getAsIdentifier()));
case NestedNameSpecifier::Namespace:
- if (auto *NS =
- cast_or_null<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
- return NestedNameSpecifier::Create(ToContext, prefix, NS);
- }
- return nullptr;
+ if (ExpectedDecl NSOrErr = Import(FromNNS->getAsNamespace())) {
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ cast<NamespaceDecl>(*NSOrErr));
+ } else
+ return NSOrErr.takeError();
case NestedNameSpecifier::NamespaceAlias:
- if (auto *NSAD =
- cast_or_null<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
- return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
- }
- return nullptr;
+ if (ExpectedDecl NSADOrErr = Import(FromNNS->getAsNamespaceAlias()))
+ return NestedNameSpecifier::Create(ToContext, Prefix,
+ cast<NamespaceAliasDecl>(*NSADOrErr));
+ else
+ return NSADOrErr.takeError();
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
case NestedNameSpecifier::Super:
- if (auto *RD =
- cast_or_null<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
- return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
- }
- return nullptr;
+ if (ExpectedDecl RDOrErr = Import(FromNNS->getAsRecordDecl()))
+ return NestedNameSpecifier::SuperSpecifier(ToContext,
+ cast<CXXRecordDecl>(*RDOrErr));
+ else
+ return RDOrErr.takeError();
case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::TypeSpecWithTemplate: {
- QualType T = Import(QualType(FromNNS->getAsType(), 0u));
- if (!T.isNull()) {
- bool bTemplate = FromNNS->getKind() ==
- NestedNameSpecifier::TypeSpecWithTemplate;
- return NestedNameSpecifier::Create(ToContext, prefix,
- bTemplate, T.getTypePtr());
- }
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ if (Expected<QualType> TyOrErr =
+ Import(QualType(FromNNS->getAsType(), 0u))) {
+ bool TSTemplate =
+ FromNNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate;
+ return NestedNameSpecifier::Create(ToContext, Prefix, TSTemplate,
+ TyOrErr->getTypePtr());
+ } else {
+ return TyOrErr.takeError();
}
- return nullptr;
}
llvm_unreachable("Invalid nested name specifier kind");
}
Expected<NestedNameSpecifierLoc>
-ASTImporter::Import_New(NestedNameSpecifierLoc FromNNS) {
- NestedNameSpecifierLoc ToNNS = Import(FromNNS);
- return ToNNS;
-}
-NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
+ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
// Copied from NestedNameSpecifier mostly.
SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
NestedNameSpecifierLoc NNS = FromNNS;
@@ -7980,54 +8163,62 @@ NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
while (!NestedNames.empty()) {
NNS = NestedNames.pop_back_val();
- NestedNameSpecifier *Spec = Import(NNS.getNestedNameSpecifier());
- if (!Spec)
- return NestedNameSpecifierLoc();
+ NestedNameSpecifier *Spec = nullptr;
+ if (Error Err = importInto(Spec, NNS.getNestedNameSpecifier()))
+ return std::move(Err);
NestedNameSpecifier::SpecifierKind Kind = Spec->getKind();
+
+ SourceLocation ToLocalBeginLoc, ToLocalEndLoc;
+ if (Kind != NestedNameSpecifier::Super) {
+ if (Error Err = importInto(ToLocalBeginLoc, NNS.getLocalBeginLoc()))
+ return std::move(Err);
+
+ if (Kind != NestedNameSpecifier::Global)
+ if (Error Err = importInto(ToLocalEndLoc, NNS.getLocalEndLoc()))
+ return std::move(Err);
+ }
+
switch (Kind) {
case NestedNameSpecifier::Identifier:
- Builder.Extend(getToContext(),
- Spec->getAsIdentifier(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsIdentifier(), ToLocalBeginLoc,
+ ToLocalEndLoc);
break;
case NestedNameSpecifier::Namespace:
- Builder.Extend(getToContext(),
- Spec->getAsNamespace(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsNamespace(), ToLocalBeginLoc,
+ ToLocalEndLoc);
break;
case NestedNameSpecifier::NamespaceAlias:
- Builder.Extend(getToContext(),
- Spec->getAsNamespaceAlias(),
- Import(NNS.getLocalBeginLoc()),
- Import(NNS.getLocalEndLoc()));
+ Builder.Extend(getToContext(), Spec->getAsNamespaceAlias(),
+ ToLocalBeginLoc, ToLocalEndLoc);
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
+ SourceLocation ToTLoc;
+ if (Error Err = importInto(ToTLoc, NNS.getTypeLoc().getBeginLoc()))
+ return std::move(Err);
TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo(
- QualType(Spec->getAsType(), 0));
- Builder.Extend(getToContext(),
- Import(NNS.getLocalBeginLoc()),
- TSI->getTypeLoc(),
- Import(NNS.getLocalEndLoc()));
+ QualType(Spec->getAsType(), 0), ToTLoc);
+ Builder.Extend(getToContext(), ToLocalBeginLoc, TSI->getTypeLoc(),
+ ToLocalEndLoc);
break;
}
case NestedNameSpecifier::Global:
- Builder.MakeGlobal(getToContext(), Import(NNS.getLocalBeginLoc()));
+ Builder.MakeGlobal(getToContext(), ToLocalBeginLoc);
break;
case NestedNameSpecifier::Super: {
- SourceRange ToRange = Import(NNS.getSourceRange());
- Builder.MakeSuper(getToContext(),
- Spec->getAsRecordDecl(),
- ToRange.getBegin(),
- ToRange.getEnd());
+ auto ToSourceRangeOrErr = Import(NNS.getSourceRange());
+ if (!ToSourceRangeOrErr)
+ return ToSourceRangeOrErr.takeError();
+
+ Builder.MakeSuper(getToContext(), Spec->getAsRecordDecl(),
+ ToSourceRangeOrErr->getBegin(),
+ ToSourceRangeOrErr->getEnd());
}
}
}
@@ -8035,137 +8226,126 @@ NestedNameSpecifierLoc ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
return Builder.getWithLocInContext(getToContext());
}
-Expected<TemplateName> ASTImporter::Import_New(TemplateName From) {
- TemplateName To = Import(From);
- if (To.isNull() && !From.isNull())
- return llvm::make_error<ImportError>();
- return To;
-}
-TemplateName ASTImporter::Import(TemplateName From) {
+Expected<TemplateName> ASTImporter::Import(TemplateName From) {
switch (From.getKind()) {
case TemplateName::Template:
- if (auto *ToTemplate =
- cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
- return TemplateName(ToTemplate);
-
- return {};
+ if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl()))
+ return TemplateName(cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
case TemplateName::OverloadedTemplate: {
OverloadedTemplateStorage *FromStorage = From.getAsOverloadedTemplate();
UnresolvedSet<2> ToTemplates;
for (auto *I : *FromStorage) {
- if (auto *To = cast_or_null<NamedDecl>(Import(I)))
- ToTemplates.addDecl(To);
+ if (auto ToOrErr = Import(I))
+ ToTemplates.addDecl(cast<NamedDecl>(*ToOrErr));
else
- return {};
+ return ToOrErr.takeError();
}
return ToContext.getOverloadedTemplateName(ToTemplates.begin(),
ToTemplates.end());
}
+ case TemplateName::AssumedTemplate: {
+ AssumedTemplateStorage *FromStorage = From.getAsAssumedTemplateName();
+ auto DeclNameOrErr = Import(FromStorage->getDeclName());
+ if (!DeclNameOrErr)
+ return DeclNameOrErr.takeError();
+ return ToContext.getAssumedTemplateName(*DeclNameOrErr);
+ }
+
case TemplateName::QualifiedTemplate: {
QualifiedTemplateName *QTN = From.getAsQualifiedTemplateName();
- NestedNameSpecifier *Qualifier = Import(QTN->getQualifier());
- if (!Qualifier)
- return {};
-
- if (auto *ToTemplate =
- cast_or_null<TemplateDecl>(Import(From.getAsTemplateDecl())))
- return ToContext.getQualifiedTemplateName(Qualifier,
- QTN->hasTemplateKeyword(),
- ToTemplate);
-
- return {};
+ auto QualifierOrErr = Import(QTN->getQualifier());
+ if (!QualifierOrErr)
+ return QualifierOrErr.takeError();
+
+ if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl()))
+ return ToContext.getQualifiedTemplateName(
+ *QualifierOrErr, QTN->hasTemplateKeyword(),
+ cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
}
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = From.getAsDependentTemplateName();
- NestedNameSpecifier *Qualifier = Import(DTN->getQualifier());
- if (!Qualifier)
- return {};
+ auto QualifierOrErr = Import(DTN->getQualifier());
+ if (!QualifierOrErr)
+ return QualifierOrErr.takeError();
if (DTN->isIdentifier()) {
- return ToContext.getDependentTemplateName(Qualifier,
+ return ToContext.getDependentTemplateName(*QualifierOrErr,
Import(DTN->getIdentifier()));
}
- return ToContext.getDependentTemplateName(Qualifier, DTN->getOperator());
+ return ToContext.getDependentTemplateName(*QualifierOrErr,
+ DTN->getOperator());
}
case TemplateName::SubstTemplateTemplateParm: {
- SubstTemplateTemplateParmStorage *subst
- = From.getAsSubstTemplateTemplateParm();
- auto *param =
- cast_or_null<TemplateTemplateParmDecl>(Import(subst->getParameter()));
- if (!param)
- return {};
+ SubstTemplateTemplateParmStorage *Subst =
+ From.getAsSubstTemplateTemplateParm();
+ ExpectedDecl ParamOrErr = Import(Subst->getParameter());
+ if (!ParamOrErr)
+ return ParamOrErr.takeError();
- TemplateName replacement = Import(subst->getReplacement());
- if (replacement.isNull())
- return {};
+ auto ReplacementOrErr = Import(Subst->getReplacement());
+ if (!ReplacementOrErr)
+ return ReplacementOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParm(param, replacement);
+ return ToContext.getSubstTemplateTemplateParm(
+ cast<TemplateTemplateParmDecl>(*ParamOrErr), *ReplacementOrErr);
}
case TemplateName::SubstTemplateTemplateParmPack: {
SubstTemplateTemplateParmPackStorage *SubstPack
= From.getAsSubstTemplateTemplateParmPack();
- auto *Param =
- cast_or_null<TemplateTemplateParmDecl>(
- Import(SubstPack->getParameterPack()));
- if (!Param)
- return {};
+ ExpectedDecl ParamOrErr = Import(SubstPack->getParameterPack());
+ if (!ParamOrErr)
+ return ParamOrErr.takeError();
ASTNodeImporter Importer(*this);
- Expected<TemplateArgument> ArgPack
- = Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
- if (!ArgPack) {
- llvm::consumeError(ArgPack.takeError());
- return {};
- }
+ auto ArgPackOrErr =
+ Importer.ImportTemplateArgument(SubstPack->getArgumentPack());
+ if (!ArgPackOrErr)
+ return ArgPackOrErr.takeError();
- return ToContext.getSubstTemplateTemplateParmPack(Param, *ArgPack);
+ return ToContext.getSubstTemplateTemplateParmPack(
+ cast<TemplateTemplateParmDecl>(*ParamOrErr), *ArgPackOrErr);
}
}
llvm_unreachable("Invalid template name kind");
}
-Expected<SourceLocation> ASTImporter::Import_New(SourceLocation FromLoc) {
- SourceLocation ToLoc = Import(FromLoc);
- if (ToLoc.isInvalid() && !FromLoc.isInvalid())
- return llvm::make_error<ImportError>();
- return ToLoc;
-}
-SourceLocation ASTImporter::Import(SourceLocation FromLoc) {
+Expected<SourceLocation> ASTImporter::Import(SourceLocation FromLoc) {
if (FromLoc.isInvalid())
- return {};
+ return SourceLocation{};
SourceManager &FromSM = FromContext.getSourceManager();
+ bool IsBuiltin = FromSM.isWrittenInBuiltinFile(FromLoc);
std::pair<FileID, unsigned> Decomposed = FromSM.getDecomposedLoc(FromLoc);
- FileID ToFileID = Import(Decomposed.first);
- if (ToFileID.isInvalid())
- return {};
+ Expected<FileID> ToFileIDOrErr = Import(Decomposed.first, IsBuiltin);
+ if (!ToFileIDOrErr)
+ return ToFileIDOrErr.takeError();
SourceManager &ToSM = ToContext.getSourceManager();
- return ToSM.getComposedLoc(ToFileID, Decomposed.second);
+ return ToSM.getComposedLoc(*ToFileIDOrErr, Decomposed.second);
}
-Expected<SourceRange> ASTImporter::Import_New(SourceRange FromRange) {
- SourceRange ToRange = Import(FromRange);
- return ToRange;
-}
-SourceRange ASTImporter::Import(SourceRange FromRange) {
- return SourceRange(Import(FromRange.getBegin()), Import(FromRange.getEnd()));
-}
+Expected<SourceRange> ASTImporter::Import(SourceRange FromRange) {
+ SourceLocation ToBegin, ToEnd;
+ if (Error Err = importInto(ToBegin, FromRange.getBegin()))
+ return std::move(Err);
+ if (Error Err = importInto(ToEnd, FromRange.getEnd()))
+ return std::move(Err);
-Expected<FileID> ASTImporter::Import_New(FileID FromID) {
- FileID ToID = Import(FromID);
- if (ToID.isInvalid() && FromID.isValid())
- return llvm::make_error<ImportError>();
- return ToID;
+ return SourceRange(ToBegin, ToEnd);
}
-FileID ASTImporter::Import(FileID FromID) {
+
+Expected<FileID> ASTImporter::Import(FileID FromID, bool IsBuiltin) {
llvm::DenseMap<FileID, FileID>::iterator Pos = ImportedFileIDs.find(FromID);
if (Pos != ImportedFileIDs.end())
return Pos->second;
@@ -8178,38 +8358,58 @@ FileID ASTImporter::Import(FileID FromID) {
FileID ToID;
if (FromSLoc.isExpansion()) {
const SrcMgr::ExpansionInfo &FromEx = FromSLoc.getExpansion();
- SourceLocation ToSpLoc = Import(FromEx.getSpellingLoc());
- SourceLocation ToExLocS = Import(FromEx.getExpansionLocStart());
+ ExpectedSLoc ToSpLoc = Import(FromEx.getSpellingLoc());
+ if (!ToSpLoc)
+ return ToSpLoc.takeError();
+ ExpectedSLoc ToExLocS = Import(FromEx.getExpansionLocStart());
+ if (!ToExLocS)
+ return ToExLocS.takeError();
unsigned TokenLen = FromSM.getFileIDSize(FromID);
SourceLocation MLoc;
if (FromEx.isMacroArgExpansion()) {
- MLoc = ToSM.createMacroArgExpansionLoc(ToSpLoc, ToExLocS, TokenLen);
+ MLoc = ToSM.createMacroArgExpansionLoc(*ToSpLoc, *ToExLocS, TokenLen);
} else {
- SourceLocation ToExLocE = Import(FromEx.getExpansionLocEnd());
- MLoc = ToSM.createExpansionLoc(ToSpLoc, ToExLocS, ToExLocE, TokenLen,
- FromEx.isExpansionTokenRange());
+ if (ExpectedSLoc ToExLocE = Import(FromEx.getExpansionLocEnd()))
+ MLoc = ToSM.createExpansionLoc(*ToSpLoc, *ToExLocS, *ToExLocE, TokenLen,
+ FromEx.isExpansionTokenRange());
+ else
+ return ToExLocE.takeError();
}
ToID = ToSM.getFileID(MLoc);
} else {
- // Include location of this file.
- SourceLocation ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
-
const SrcMgr::ContentCache *Cache = FromSLoc.getFile().getContentCache();
- if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
- // FIXME: We probably want to use getVirtualFile(), so we don't hit the
- // disk again
- // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
- // than mmap the files several times.
- const FileEntry *Entry =
- ToFileManager.getFile(Cache->OrigEntry->getName());
- if (!Entry)
- return {};
- ToID = ToSM.createFileID(Entry, ToIncludeLoc,
- FromSLoc.getFile().getFileCharacteristic());
- } else {
+
+ if (!IsBuiltin) {
+ // Include location of this file.
+ ExpectedSLoc ToIncludeLoc = Import(FromSLoc.getFile().getIncludeLoc());
+ if (!ToIncludeLoc)
+ return ToIncludeLoc.takeError();
+
+ if (Cache->OrigEntry && Cache->OrigEntry->getDir()) {
+ // FIXME: We probably want to use getVirtualFile(), so we don't hit the
+ // disk again
+ // FIXME: We definitely want to re-use the existing MemoryBuffer, rather
+ // than mmap the files several times.
+ const FileEntry *Entry =
+ ToFileManager.getFile(Cache->OrigEntry->getName());
+ // FIXME: The filename may be a virtual name that does probably not
+ // point to a valid file and we get no Entry here. In this case try with
+ // the memory buffer below.
+ if (Entry)
+ ToID = ToSM.createFileID(Entry, *ToIncludeLoc,
+ FromSLoc.getFile().getFileCharacteristic());
+ }
+ }
+
+ if (ToID.isInvalid() || IsBuiltin) {
// FIXME: We want to re-use the existing MemoryBuffer!
- const llvm::MemoryBuffer *FromBuf =
- Cache->getBuffer(FromContext.getDiagnostics(), FromSM);
+ bool Invalid = true;
+ const llvm::MemoryBuffer *FromBuf = Cache->getBuffer(
+ FromContext.getDiagnostics(), FromSM, SourceLocation{}, &Invalid);
+ if (!FromBuf || Invalid)
+ // FIXME: Use a new error kind?
+ return llvm::make_error<ImportError>(ImportError::Unknown);
+
std::unique_ptr<llvm::MemoryBuffer> ToBuf =
llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
FromBuf->getBufferIdentifier());
@@ -8218,186 +8418,187 @@ FileID ASTImporter::Import(FileID FromID) {
}
}
+ assert(ToID.isValid() && "Unexpected invalid fileID was created.");
+
ImportedFileIDs[FromID] = ToID;
return ToID;
}
-Expected<CXXCtorInitializer *>
-ASTImporter::Import_New(CXXCtorInitializer *From) {
- CXXCtorInitializer *To = Import(From);
- if (!To && From)
- return llvm::make_error<ImportError>();
- return To;
-}
-CXXCtorInitializer *ASTImporter::Import(CXXCtorInitializer *From) {
- Expr *ToExpr = Import(From->getInit());
- if (!ToExpr && From->getInit())
- return nullptr;
+Expected<CXXCtorInitializer *> ASTImporter::Import(CXXCtorInitializer *From) {
+ ExpectedExpr ToExprOrErr = Import(From->getInit());
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
+
+ auto LParenLocOrErr = Import(From->getLParenLoc());
+ if (!LParenLocOrErr)
+ return LParenLocOrErr.takeError();
+
+ auto RParenLocOrErr = Import(From->getRParenLoc());
+ if (!RParenLocOrErr)
+ return RParenLocOrErr.takeError();
if (From->isBaseInitializer()) {
- TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
- if (!ToTInfo && From->getTypeSourceInfo())
- return nullptr;
+ auto ToTInfoOrErr = Import(From->getTypeSourceInfo());
+ if (!ToTInfoOrErr)
+ return ToTInfoOrErr.takeError();
+
+ SourceLocation EllipsisLoc;
+ if (From->isPackExpansion())
+ if (Error Err = importInto(EllipsisLoc, From->getEllipsisLoc()))
+ return std::move(Err);
return new (ToContext) CXXCtorInitializer(
- ToContext, ToTInfo, From->isBaseVirtual(), Import(From->getLParenLoc()),
- ToExpr, Import(From->getRParenLoc()),
- From->isPackExpansion() ? Import(From->getEllipsisLoc())
- : SourceLocation());
+ ToContext, *ToTInfoOrErr, From->isBaseVirtual(), *LParenLocOrErr,
+ *ToExprOrErr, *RParenLocOrErr, EllipsisLoc);
} else if (From->isMemberInitializer()) {
- auto *ToField = cast_or_null<FieldDecl>(Import(From->getMember()));
- if (!ToField && From->getMember())
- return nullptr;
+ ExpectedDecl ToFieldOrErr = Import(From->getMember());
+ if (!ToFieldOrErr)
+ return ToFieldOrErr.takeError();
+
+ auto MemberLocOrErr = Import(From->getMemberLocation());
+ if (!MemberLocOrErr)
+ return MemberLocOrErr.takeError();
return new (ToContext) CXXCtorInitializer(
- ToContext, ToField, Import(From->getMemberLocation()),
- Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()));
+ ToContext, cast_or_null<FieldDecl>(*ToFieldOrErr), *MemberLocOrErr,
+ *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
} else if (From->isIndirectMemberInitializer()) {
- auto *ToIField = cast_or_null<IndirectFieldDecl>(
- Import(From->getIndirectMember()));
- if (!ToIField && From->getIndirectMember())
- return nullptr;
+ ExpectedDecl ToIFieldOrErr = Import(From->getIndirectMember());
+ if (!ToIFieldOrErr)
+ return ToIFieldOrErr.takeError();
+
+ auto MemberLocOrErr = Import(From->getMemberLocation());
+ if (!MemberLocOrErr)
+ return MemberLocOrErr.takeError();
return new (ToContext) CXXCtorInitializer(
- ToContext, ToIField, Import(From->getMemberLocation()),
- Import(From->getLParenLoc()), ToExpr, Import(From->getRParenLoc()));
+ ToContext, cast_or_null<IndirectFieldDecl>(*ToIFieldOrErr),
+ *MemberLocOrErr, *LParenLocOrErr, *ToExprOrErr, *RParenLocOrErr);
} else if (From->isDelegatingInitializer()) {
- TypeSourceInfo *ToTInfo = Import(From->getTypeSourceInfo());
- if (!ToTInfo && From->getTypeSourceInfo())
- return nullptr;
+ auto ToTInfoOrErr = Import(From->getTypeSourceInfo());
+ if (!ToTInfoOrErr)
+ return ToTInfoOrErr.takeError();
return new (ToContext)
- CXXCtorInitializer(ToContext, ToTInfo, Import(From->getLParenLoc()),
- ToExpr, Import(From->getRParenLoc()));
+ CXXCtorInitializer(ToContext, *ToTInfoOrErr, *LParenLocOrErr,
+ *ToExprOrErr, *RParenLocOrErr);
} else {
- return nullptr;
+ // FIXME: assert?
+ return make_error<ImportError>();
}
}
Expected<CXXBaseSpecifier *>
-ASTImporter::Import_New(const CXXBaseSpecifier *From) {
- CXXBaseSpecifier *To = Import(From);
- if (!To && From)
- return llvm::make_error<ImportError>();
- return To;
-}
-CXXBaseSpecifier *ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
+ASTImporter::Import(const CXXBaseSpecifier *BaseSpec) {
auto Pos = ImportedCXXBaseSpecifiers.find(BaseSpec);
if (Pos != ImportedCXXBaseSpecifiers.end())
return Pos->second;
+ Expected<SourceRange> ToSourceRange = Import(BaseSpec->getSourceRange());
+ if (!ToSourceRange)
+ return ToSourceRange.takeError();
+ Expected<TypeSourceInfo *> ToTSI = Import(BaseSpec->getTypeSourceInfo());
+ if (!ToTSI)
+ return ToTSI.takeError();
+ ExpectedSLoc ToEllipsisLoc = Import(BaseSpec->getEllipsisLoc());
+ if (!ToEllipsisLoc)
+ return ToEllipsisLoc.takeError();
CXXBaseSpecifier *Imported = new (ToContext) CXXBaseSpecifier(
- Import(BaseSpec->getSourceRange()),
- BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
- BaseSpec->getAccessSpecifierAsWritten(),
- Import(BaseSpec->getTypeSourceInfo()),
- Import(BaseSpec->getEllipsisLoc()));
+ *ToSourceRange, BaseSpec->isVirtual(), BaseSpec->isBaseOfClass(),
+ BaseSpec->getAccessSpecifierAsWritten(), *ToTSI, *ToEllipsisLoc);
ImportedCXXBaseSpecifiers[BaseSpec] = Imported;
return Imported;
}
-Error ASTImporter::ImportDefinition_New(Decl *From) {
- Decl *To = Import(From);
- if (!To)
- return llvm::make_error<ImportError>();
+Error ASTImporter::ImportDefinition(Decl *From) {
+ ExpectedDecl ToOrErr = Import(From);
+ if (!ToOrErr)
+ return ToOrErr.takeError();
+ Decl *To = *ToOrErr;
- if (auto *FromDC = cast<DeclContext>(From)) {
- ASTNodeImporter Importer(*this);
+ auto *FromDC = cast<DeclContext>(From);
+ ASTNodeImporter Importer(*this);
- if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
- if (!ToRecord->getDefinition()) {
- return Importer.ImportDefinition(
- cast<RecordDecl>(FromDC), ToRecord,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToRecord = dyn_cast<RecordDecl>(To)) {
+ if (!ToRecord->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<RecordDecl>(FromDC), ToRecord,
+ ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
- if (!ToEnum->getDefinition()) {
- return Importer.ImportDefinition(
- cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToEnum = dyn_cast<EnumDecl>(To)) {
+ if (!ToEnum->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<EnumDecl>(FromDC), ToEnum, ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
- if (!ToIFace->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCInterfaceDecl>(FromDC), ToIFace,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToIFace = dyn_cast<ObjCInterfaceDecl>(To)) {
+ if (!ToIFace->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<ObjCInterfaceDecl>(FromDC), ToIFace,
+ ASTNodeImporter::IDK_Everything);
}
+ }
- if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
- if (!ToProto->getDefinition()) {
- return Importer.ImportDefinition(
- cast<ObjCProtocolDecl>(FromDC), ToProto,
- ASTNodeImporter::IDK_Everything);
- }
+ if (auto *ToProto = dyn_cast<ObjCProtocolDecl>(To)) {
+ if (!ToProto->getDefinition()) {
+ return Importer.ImportDefinition(
+ cast<ObjCProtocolDecl>(FromDC), ToProto,
+ ASTNodeImporter::IDK_Everything);
}
-
- return Importer.ImportDeclContext(FromDC, true);
}
- return Error::success();
+ return Importer.ImportDeclContext(FromDC, true);
}
-void ASTImporter::ImportDefinition(Decl *From) {
- Error Err = ImportDefinition_New(From);
- llvm::consumeError(std::move(Err));
-}
-
-Expected<DeclarationName> ASTImporter::Import_New(DeclarationName FromName) {
- DeclarationName ToName = Import(FromName);
- if (!ToName && FromName)
- return llvm::make_error<ImportError>();
- return ToName;
-}
-DeclarationName ASTImporter::Import(DeclarationName FromName) {
+Expected<DeclarationName> ASTImporter::Import(DeclarationName FromName) {
if (!FromName)
- return {};
+ return DeclarationName{};
switch (FromName.getNameKind()) {
case DeclarationName::Identifier:
- return Import(FromName.getAsIdentifierInfo());
+ return DeclarationName(Import(FromName.getAsIdentifierInfo()));
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
- return Import(FromName.getObjCSelector());
+ if (auto ToSelOrErr = Import(FromName.getObjCSelector()))
+ return DeclarationName(*ToSelOrErr);
+ else
+ return ToSelOrErr.takeError();
case DeclarationName::CXXConstructorName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXConstructorName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXConstructorName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXDestructorName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXDestructorName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXDestructorName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXDeductionGuideName: {
- auto *Template = cast_or_null<TemplateDecl>(
- Import(FromName.getCXXDeductionGuideTemplate()));
- if (!Template)
- return {};
- return ToContext.DeclarationNames.getCXXDeductionGuideName(Template);
+ if (auto ToTemplateOrErr = Import(FromName.getCXXDeductionGuideTemplate()))
+ return ToContext.DeclarationNames.getCXXDeductionGuideName(
+ cast<TemplateDecl>(*ToTemplateOrErr));
+ else
+ return ToTemplateOrErr.takeError();
}
case DeclarationName::CXXConversionFunctionName: {
- QualType T = Import(FromName.getCXXNameType());
- if (T.isNull())
- return {};
-
- return ToContext.DeclarationNames.getCXXConversionFunctionName(
- ToContext.getCanonicalType(T));
+ if (auto ToTyOrErr = Import(FromName.getCXXNameType()))
+ return ToContext.DeclarationNames.getCXXConversionFunctionName(
+ ToContext.getCanonicalType(*ToTyOrErr));
+ else
+ return ToTyOrErr.takeError();
}
case DeclarationName::CXXOperatorName:
@@ -8406,7 +8607,7 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
case DeclarationName::CXXLiteralOperatorName:
return ToContext.DeclarationNames.getCXXLiteralOperatorName(
- Import(FromName.getCXXLiteralIdentifier()));
+ Import(FromName.getCXXLiteralIdentifier()));
case DeclarationName::CXXUsingDirective:
// FIXME: STATICS!
@@ -8428,15 +8629,9 @@ IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
return ToId;
}
-Expected<Selector> ASTImporter::Import_New(Selector FromSel) {
- Selector ToSel = Import(FromSel);
- if (ToSel.isNull() && !FromSel.isNull())
- return llvm::make_error<ImportError>();
- return ToSel;
-}
-Selector ASTImporter::Import(Selector FromSel) {
+Expected<Selector> ASTImporter::Import(Selector FromSel) {
if (FromSel.isNull())
- return {};
+ return Selector{};
SmallVector<IdentifierInfo *, 4> Idents;
Idents.push_back(Import(FromSel.getIdentifierInfoForSlot(0)));
@@ -8496,15 +8691,42 @@ Decl *ASTImporter::MapImported(Decl *From, Decl *To) {
if (Pos != ImportedDecls.end())
return Pos->second;
ImportedDecls[From] = To;
+ // This mapping should be maintained only in this function. Therefore do not
+ // check for additional consistency.
+ ImportedFromDecls[To] = From;
+ AddToLookupTable(To);
return To;
}
+llvm::Optional<ImportError>
+ASTImporter::getImportDeclErrorIfAny(Decl *FromD) const {
+ auto Pos = ImportDeclErrors.find(FromD);
+ if (Pos != ImportDeclErrors.end())
+ return Pos->second;
+ else
+ return Optional<ImportError>();
+}
+
+void ASTImporter::setImportDeclError(Decl *From, ImportError Error) {
+ auto InsertRes = ImportDeclErrors.insert({From, Error});
+ (void)InsertRes;
+ // Either we set the error for the first time, or we already had set one and
+ // now we want to set the same error.
+ assert(InsertRes.second || InsertRes.first->second.Error == Error.Error);
+}
+
bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
bool Complain) {
- llvm::DenseMap<const Type *, const Type *>::iterator Pos
- = ImportedTypes.find(From.getTypePtr());
- if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
- return true;
+ llvm::DenseMap<const Type *, const Type *>::iterator Pos =
+ ImportedTypes.find(From.getTypePtr());
+ if (Pos != ImportedTypes.end()) {
+ if (ExpectedType ToFromOrErr = Import(From)) {
+ if (ToContext.hasSameType(*ToFromOrErr, To))
+ return true;
+ } else {
+ llvm::consumeError(ToFromOrErr.takeError());
+ }
+ }
StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
getStructuralEquivalenceKind(*this), false,
diff --git a/lib/AST/ASTImporterLookupTable.cpp b/lib/AST/ASTImporterLookupTable.cpp
index fbcd4f5cb341..7390329d4ed8 100644
--- a/lib/AST/ASTImporterLookupTable.cpp
+++ b/lib/AST/ASTImporterLookupTable.cpp
@@ -1,9 +1,8 @@
//===- ASTImporterLookupTable.cpp - ASTImporter specific lookup -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -27,17 +26,30 @@ struct Builder : RecursiveASTVisitor<Builder> {
LT.add(D);
return true;
}
+ // In most cases the FriendDecl contains the declaration of the befriended
+ // class as a child node, so it is discovered during the recursive
+ // visitation. However, there are cases when the befriended class is not a
+ // child, thus it must be fetched explicitly from the FriendDecl, and only
+ // then can we add it to the lookup table.
bool VisitFriendDecl(FriendDecl *D) {
if (D->getFriendType()) {
QualType Ty = D->getFriendType()->getType();
- // FIXME Can this be other than elaborated?
- QualType NamedTy = cast<ElaboratedType>(Ty)->getNamedType();
- if (!NamedTy->isDependentType()) {
- if (const auto *RTy = dyn_cast<RecordType>(NamedTy))
+ if (isa<ElaboratedType>(Ty))
+ Ty = cast<ElaboratedType>(Ty)->getNamedType();
+ // A FriendDecl with a dependent type (e.g. ClassTemplateSpecialization)
+ // always has that decl as child node.
+ // However, there are non-dependent cases which does not have the
+ // type as a child node. We have to dig up that type now.
+ if (!Ty->isDependentType()) {
+ if (const auto *RTy = dyn_cast<RecordType>(Ty))
LT.add(RTy->getAsCXXRecordDecl());
- else if (const auto *SpecTy =
- dyn_cast<TemplateSpecializationType>(NamedTy)) {
+ else if (const auto *SpecTy = dyn_cast<TemplateSpecializationType>(Ty))
LT.add(SpecTy->getAsCXXRecordDecl());
+ else if (isa<TypedefType>(Ty)) {
+ // We do not put friend typedefs to the lookup table because
+ // ASTImporter does not organize typedefs into redecl chains.
+ } else {
+ llvm_unreachable("Unhandled type of friend class");
}
}
}
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index d19b89bb95b4..912db3c130c5 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -1,9 +1,8 @@
//===- ASTStructuralEquivalence.cpp ---------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -74,6 +73,7 @@
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
@@ -101,6 +101,59 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const TemplateArgument &Arg1,
const TemplateArgument &Arg2);
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ NestedNameSpecifier *NNS1,
+ NestedNameSpecifier *NNS2);
+static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
+ const IdentifierInfo *Name2);
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ const DeclarationName Name1,
+ const DeclarationName Name2) {
+ if (Name1.getNameKind() != Name2.getNameKind())
+ return false;
+
+ switch (Name1.getNameKind()) {
+
+ case DeclarationName::Identifier:
+ return IsStructurallyEquivalent(Name1.getAsIdentifierInfo(),
+ Name2.getAsIdentifierInfo());
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ return IsStructurallyEquivalent(Context, Name1.getCXXNameType(),
+ Name2.getCXXNameType());
+
+ case DeclarationName::CXXDeductionGuideName: {
+ if (!IsStructurallyEquivalent(
+ Context, Name1.getCXXDeductionGuideTemplate()->getDeclName(),
+ Name2.getCXXDeductionGuideTemplate()->getDeclName()))
+ return false;
+ return IsStructurallyEquivalent(Context,
+ Name1.getCXXDeductionGuideTemplate(),
+ Name2.getCXXDeductionGuideTemplate());
+ }
+
+ case DeclarationName::CXXOperatorName:
+ return Name1.getCXXOverloadedOperator() == Name2.getCXXOverloadedOperator();
+
+ case DeclarationName::CXXLiteralOperatorName:
+ return IsStructurallyEquivalent(Name1.getCXXLiteralIdentifier(),
+ Name2.getCXXLiteralIdentifier());
+
+ case DeclarationName::CXXUsingDirective:
+ return true; // FIXME When do we consider two using directives equal?
+
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ return true; // FIXME
+ }
+
+ llvm_unreachable("Unhandled kind of DeclarationName");
+ return true;
+}
/// Determine structural equivalence of two expressions.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
@@ -108,7 +161,26 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!E1 || !E2)
return E1 == E2;
- // FIXME: Actually perform a structural comparison!
+ if (auto *DE1 = dyn_cast<DependentScopeDeclRefExpr>(E1)) {
+ auto *DE2 = dyn_cast<DependentScopeDeclRefExpr>(E2);
+ if (!DE2)
+ return false;
+ if (!IsStructurallyEquivalent(Context, DE1->getDeclName(),
+ DE2->getDeclName()))
+ return false;
+ return IsStructurallyEquivalent(Context, DE1->getQualifier(),
+ DE2->getQualifier());
+ } else if (auto CastE1 = dyn_cast<ImplicitCastExpr>(E1)) {
+ auto *CastE2 = dyn_cast<ImplicitCastExpr>(E2);
+ if (!CastE2)
+ return false;
+ if (!IsStructurallyEquivalent(Context, CastE1->getType(),
+ CastE2->getType()))
+ return false;
+ return IsStructurallyEquivalent(Context, CastE1->getSubExpr(),
+ CastE2->getSubExpr());
+ }
+ // FIXME: Handle other kind of expressions!
return true;
}
@@ -181,6 +253,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return I1 == E1 && I2 == E2;
}
+ case TemplateName::AssumedTemplate: {
+ AssumedTemplateStorage *TN1 = N1.getAsAssumedTemplateName(),
+ *TN2 = N1.getAsAssumedTemplateName();
+ return TN1->getDeclName() == TN2->getDeclName();
+ }
+
case TemplateName::QualifiedTemplate: {
QualifiedTemplateName *QN1 = N1.getAsQualifiedTemplateName(),
*QN2 = N2.getAsQualifiedTemplateName();
@@ -297,6 +375,62 @@ static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
}
+/// Determine structural equivalence based on the ExtInfo of functions. This
+/// is inspired by ASTContext::mergeFunctionTypes(), we compare calling
+/// conventions bits but must not compare some other bits.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ FunctionType::ExtInfo EI1,
+ FunctionType::ExtInfo EI2) {
+ // Compatible functions must have compatible calling conventions.
+ if (EI1.getCC() != EI2.getCC())
+ return false;
+
+ // Regparm is part of the calling convention.
+ if (EI1.getHasRegParm() != EI2.getHasRegParm())
+ return false;
+ if (EI1.getRegParm() != EI2.getRegParm())
+ return false;
+
+ if (EI1.getProducesResult() != EI2.getProducesResult())
+ return false;
+ if (EI1.getNoCallerSavedRegs() != EI2.getNoCallerSavedRegs())
+ return false;
+ if (EI1.getNoCfCheck() != EI2.getNoCfCheck())
+ return false;
+
+ return true;
+}
+
+/// Check the equivalence of exception specifications.
+static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
+ const FunctionProtoType *Proto1,
+ const FunctionProtoType *Proto2) {
+
+ auto Spec1 = Proto1->getExceptionSpecType();
+ auto Spec2 = Proto2->getExceptionSpecType();
+
+ if (isUnresolvedExceptionSpec(Spec1) || isUnresolvedExceptionSpec(Spec2))
+ return true;
+
+ if (Spec1 != Spec2)
+ return false;
+ if (Spec1 == EST_Dynamic) {
+ if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+ return false;
+ for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+ Proto2->getExceptionType(I)))
+ return false;
+ }
+ } else if (isComputedNoexcept(Spec1)) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+ Proto2->getNoexceptExpr()))
+ return false;
+ }
+
+ return true;
+}
+
/// Determine structural equivalence of two types.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
QualType T1, QualType T2) {
@@ -503,7 +637,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Proto1->isVariadic() != Proto2->isVariadic())
return false;
- if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
+ if (Proto1->getMethodQuals() != Proto2->getMethodQuals())
return false;
// Check exceptions, this information is lost in canonical type.
@@ -511,24 +645,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
cast<FunctionProtoType>(OrigT1.getDesugaredType(Context.FromCtx));
const auto *OrigProto2 =
cast<FunctionProtoType>(OrigT2.getDesugaredType(Context.ToCtx));
- auto Spec1 = OrigProto1->getExceptionSpecType();
- auto Spec2 = OrigProto2->getExceptionSpecType();
-
- if (Spec1 != Spec2)
+ if (!IsEquivalentExceptionSpec(Context, OrigProto1, OrigProto2))
return false;
- if (Spec1 == EST_Dynamic) {
- if (OrigProto1->getNumExceptions() != OrigProto2->getNumExceptions())
- return false;
- for (unsigned I = 0, N = OrigProto1->getNumExceptions(); I != N; ++I) {
- if (!IsStructurallyEquivalent(Context, OrigProto1->getExceptionType(I),
- OrigProto2->getExceptionType(I)))
- return false;
- }
- } else if (isComputedNoexcept(Spec1)) {
- if (!IsStructurallyEquivalent(Context, OrigProto1->getNoexceptExpr(),
- OrigProto2->getNoexceptExpr()))
- return false;
- }
// Fall through to check the bits common with FunctionNoProtoType.
LLVM_FALLTHROUGH;
@@ -540,7 +658,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
Function2->getReturnType()))
return false;
- if (Function1->getExtInfo() != Function2->getExtInfo())
+ if (!IsStructurallyEquivalent(Context, Function1->getExtInfo(),
+ Function2->getExtInfo()))
return false;
break;
}
@@ -569,6 +688,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
+ case Type::MacroQualified:
+ if (!IsStructurallyEquivalent(
+ Context, cast<MacroQualifiedType>(T1)->getUnderlyingType(),
+ cast<MacroQualifiedType>(T2)->getUnderlyingType()))
+ return false;
+ break;
+
case Type::Typedef:
if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
cast<TypedefType>(T2)->getDecl()))
@@ -834,10 +960,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
IdentifierInfo *Name2 = Field2->getIdentifier();
if (!::IsStructurallyEquivalent(Name1, Name2)) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field_name)
<< Field2->getDeclName();
@@ -850,10 +975,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, Field1->getType(),
Field2->getType())) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@@ -865,10 +989,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field1->isBitField() != Field2->isBitField()) {
if (Context.Complain) {
- Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(
+ Owner2->getLocation(),
+ Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
if (Field1->isBitField()) {
Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
@@ -895,9 +1018,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Bits1 != Bits2) {
if (Context.Complain) {
Context.Diag2(Owner2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(Owner2);
Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
<< Field2->getDeclName() << Field2->getType() << Bits2;
@@ -933,13 +1055,15 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (auto *Constructor1 = dyn_cast<CXXConstructorDecl>(Method1)) {
auto *Constructor2 = cast<CXXConstructorDecl>(Method2);
- if (Constructor1->isExplicit() != Constructor2->isExplicit())
+ if (!Constructor1->getExplicitSpecifier().isEquivalent(
+ Constructor2->getExplicitSpecifier()))
return false;
}
if (auto *Conversion1 = dyn_cast<CXXConversionDecl>(Method1)) {
auto *Conversion2 = cast<CXXConversionDecl>(Method2);
- if (Conversion1->isExplicit() != Conversion2->isExplicit())
+ if (!Conversion1->getExplicitSpecifier().isEquivalent(
+ Conversion2->getExplicitSpecifier()))
return false;
if (!IsStructurallyEquivalent(Context, Conversion1->getConversionType(),
Conversion2->getConversionType()))
@@ -961,15 +1085,26 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return true;
}
+/// Determine structural equivalence of two lambda classes.
+static bool
+IsStructurallyEquivalentLambdas(StructuralEquivalenceContext &Context,
+ CXXRecordDecl *D1, CXXRecordDecl *D2) {
+ assert(D1->isLambda() && D2->isLambda() &&
+ "Must be called on lambda classes");
+ if (!IsStructurallyEquivalent(Context, D1->getLambdaCallOperator(),
+ D2->getLambdaCallOperator()))
+ return false;
+
+ return true;
+}
+
/// Determine structural equivalence of two records.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
RecordDecl *D1, RecordDecl *D2) {
if (D1->isUnion() != D2->isUnion()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
<< D1->getDeclName() << (unsigned)D1->getTagKind();
@@ -1044,9 +1179,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
}
+ if (D1CXX->isLambda() != D2CXX->isLambda())
+ return false;
+ if (D1CXX->isLambda()) {
+ if (!IsStructurallyEquivalentLambdas(Context, D1CXX, D2CXX))
+ return false;
+ }
+
if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
<< D2CXX->getNumBases();
@@ -1065,7 +1209,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Base2->getType())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
<< Base2->getType() << Base2->getSourceRange();
@@ -1079,7 +1224,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Base1->isVirtual() != Base2->isVirtual()) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
<< Base2->isVirtual() << Base2->getSourceRange();
@@ -1092,15 +1238,16 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Check the friends for consistency.
CXXRecordDecl::friend_iterator Friend2 = D2CXX->friend_begin(),
- Friend2End = D2CXX->friend_end();
+ Friend2End = D2CXX->friend_end();
for (CXXRecordDecl::friend_iterator Friend1 = D1CXX->friend_begin(),
- Friend1End = D1CXX->friend_end();
+ Friend1End = D1CXX->friend_end();
Friend1 != Friend1End; ++Friend1, ++Friend2) {
if (Friend2 == Friend2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2CXX);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
}
@@ -1109,8 +1256,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, *Friend1, *Friend2)) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2CXX);
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2CXX);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
}
@@ -1120,8 +1269,10 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Friend2 != Friend2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
- << Context.ToCtx.getTypeDeclType(D2);
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
+ << Context.ToCtx.getTypeDeclType(D2);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
}
@@ -1129,7 +1280,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
} else if (D1CXX->getNumBases() > 0) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
@@ -1149,9 +1302,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field2 == Field2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(Field1->getLocation(), diag::note_odr_field)
<< Field1->getDeclName() << Field1->getType();
@@ -1166,10 +1318,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Field2 != Field2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@@ -1200,9 +1350,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (EC2 == EC2End) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
<< EC1->getDeclName() << EC1->getInitVal().toString(10);
@@ -1217,9 +1366,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
!IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1232,10 +1380,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (EC2 != EC2End) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(),
- Context.ErrorOnTagTypeMismatch
- ? diag::err_odr_tag_type_inconsistent
- : diag::warn_odr_tag_type_inconsistent)
+ Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
+ diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
<< EC2->getDeclName() << EC2->getInitVal().toString(10);
@@ -1253,7 +1399,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Params1->size() != Params2->size()) {
if (Context.Complain) {
Context.Diag2(Params2->getTemplateLoc(),
- diag::err_odr_different_num_template_parameters)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_different_num_template_parameters))
<< Params1->size() << Params2->size();
Context.Diag1(Params1->getTemplateLoc(),
diag::note_odr_template_parameter_list);
@@ -1265,7 +1412,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
if (Context.Complain) {
Context.Diag2(Params2->getParam(I)->getLocation(),
- diag::err_odr_different_template_parameter_kind);
+ Context.getApplicableDiagnostic(
+ diag::err_odr_different_template_parameter_kind));
Context.Diag1(Params1->getParam(I)->getLocation(),
diag::note_odr_template_parameter_here);
}
@@ -1285,7 +1433,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
TemplateTypeParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1301,7 +1451,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
NonTypeTemplateParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1313,7 +1465,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (!IsStructurallyEquivalent(Context, D1->getType(), D2->getType())) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
- diag::err_odr_non_type_parameter_type_inconsistent)
+ Context.getApplicableDiagnostic(
+ diag::err_odr_non_type_parameter_type_inconsistent))
<< D2->getType() << D1->getType();
Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
<< D1->getType();
@@ -1329,7 +1482,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
TemplateTemplateParmDecl *D2) {
if (D1->isParameterPack() != D2->isParameterPack()) {
if (Context.Complain) {
- Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+ Context.Diag2(D2->getLocation(),
+ Context.getApplicableDiagnostic(
+ diag::err_odr_parameter_pack_non_pack))
<< D2->isParameterPack();
Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
<< D1->isParameterPack();
@@ -1378,6 +1533,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ ConceptDecl *D1,
+ ConceptDecl *D2) {
+ // Check template parameters.
+ if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
+ return false;
+
+ // Check the constraint expression.
+ return IsStructurallyEquivalent(Context, D1->getConstraintExpr(),
+ D2->getConstraintExpr());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
FriendDecl *D1, FriendDecl *D2) {
if ((D1->getFriendType() && D2->getFriendDecl()) ||
(D1->getFriendDecl() && D2->getFriendType())) {
@@ -1485,6 +1652,52 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
return Index;
}
+unsigned StructuralEquivalenceContext::getApplicableDiagnostic(
+ unsigned ErrorDiagnostic) {
+ if (ErrorOnTagTypeMismatch)
+ return ErrorDiagnostic;
+
+ switch (ErrorDiagnostic) {
+ case diag::err_odr_variable_type_inconsistent:
+ return diag::warn_odr_variable_type_inconsistent;
+ case diag::err_odr_variable_multiple_def:
+ return diag::warn_odr_variable_multiple_def;
+ case diag::err_odr_function_type_inconsistent:
+ return diag::warn_odr_function_type_inconsistent;
+ case diag::err_odr_tag_type_inconsistent:
+ return diag::warn_odr_tag_type_inconsistent;
+ case diag::err_odr_field_type_inconsistent:
+ return diag::warn_odr_field_type_inconsistent;
+ case diag::err_odr_ivar_type_inconsistent:
+ return diag::warn_odr_ivar_type_inconsistent;
+ case diag::err_odr_objc_superclass_inconsistent:
+ return diag::warn_odr_objc_superclass_inconsistent;
+ case diag::err_odr_objc_method_result_type_inconsistent:
+ return diag::warn_odr_objc_method_result_type_inconsistent;
+ case diag::err_odr_objc_method_num_params_inconsistent:
+ return diag::warn_odr_objc_method_num_params_inconsistent;
+ case diag::err_odr_objc_method_param_type_inconsistent:
+ return diag::warn_odr_objc_method_param_type_inconsistent;
+ case diag::err_odr_objc_method_variadic_inconsistent:
+ return diag::warn_odr_objc_method_variadic_inconsistent;
+ case diag::err_odr_objc_property_type_inconsistent:
+ return diag::warn_odr_objc_property_type_inconsistent;
+ case diag::err_odr_objc_property_impl_kind_inconsistent:
+ return diag::warn_odr_objc_property_impl_kind_inconsistent;
+ case diag::err_odr_objc_synthesize_ivar_inconsistent:
+ return diag::warn_odr_objc_synthesize_ivar_inconsistent;
+ case diag::err_odr_different_num_template_parameters:
+ return diag::warn_odr_different_num_template_parameters;
+ case diag::err_odr_different_template_parameter_kind:
+ return diag::warn_odr_different_template_parameter_kind;
+ case diag::err_odr_parameter_pack_non_pack:
+ return diag::warn_odr_parameter_pack_non_pack;
+ case diag::err_odr_non_type_parameter_type_inconsistent:
+ return diag::warn_odr_non_type_parameter_type_inconsistent;
+ }
+ llvm_unreachable("Diagnostic kind not handled in preceding switch");
+}
+
bool StructuralEquivalenceContext::IsEquivalent(Decl *D1, Decl *D2) {
// Ensure that the implementation functions (all static functions in this TU)
@@ -1590,6 +1803,14 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
// Class template/non-class-template mismatch.
return false;
}
+ } else if (auto *ConceptDecl1 = dyn_cast<ConceptDecl>(D1)) {
+ if (auto *ConceptDecl2 = dyn_cast<ConceptDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, ConceptDecl1, ConceptDecl2))
+ return false;
+ } else {
+ // Concept/non-concept mismatch.
+ return false;
+ }
} else if (auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
if (auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
@@ -1624,6 +1845,12 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
}
} else if (FunctionDecl *FD1 = dyn_cast<FunctionDecl>(D1)) {
if (FunctionDecl *FD2 = dyn_cast<FunctionDecl>(D2)) {
+ if (FD1->isOverloadedOperator()) {
+ if (!FD2->isOverloadedOperator())
+ return false;
+ if (FD1->getOverloadedOperator() != FD2->getOverloadedOperator())
+ return false;
+ }
if (!::IsStructurallyEquivalent(FD1->getIdentifier(),
FD2->getIdentifier()))
return false;
diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
index 461084ce707c..ba1581bd3f6b 100644
--- a/lib/AST/ASTTypeTraits.cpp
+++ b/lib/AST/ASTTypeTraits.cpp
@@ -1,9 +1,8 @@
//===--- ASTTypeTraits.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -38,6 +37,9 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
{ NKI_None, "Type" },
#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
#include "clang/AST/TypeNodes.def"
+ { NKI_None, "OMPClause" },
+#define OPENMP_CLAUSE(TextualSpelling, Class) {NKI_OMPClause, #Class},
+#include "clang/Basic/OpenMPKinds.def"
};
bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
@@ -104,6 +106,19 @@ ASTNodeKind ASTNodeKind::getFromNode(const Type &T) {
#include "clang/AST/TypeNodes.def"
}
llvm_unreachable("invalid type kind");
+ }
+
+ASTNodeKind ASTNodeKind::getFromNode(const OMPClause &C) {
+ switch (C.getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: return ASTNodeKind(NKI_##Class);
+#include "clang/Basic/OpenMPKinds.def"
+ case OMPC_threadprivate:
+ case OMPC_uniform:
+ case OMPC_unknown:
+ llvm_unreachable("unexpected OpenMP clause kind");
+ }
+ llvm_unreachable("invalid stmt kind");
}
void DynTypedNode::print(llvm::raw_ostream &OS,
@@ -152,6 +167,8 @@ SourceRange DynTypedNode::getSourceRange() const {
return D->getSourceRange();
if (const Stmt *S = get<Stmt>())
return S->getSourceRange();
+ if (const auto *C = get<OMPClause>())
+ return SourceRange(C->getBeginLoc(), C->getEndLoc());
return SourceRange();
}
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index b06b50c9b4b8..0ef925ec1c90 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -1,9 +1,8 @@
//===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index 06295b58178b..31cb36918726 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -1,9 +1,8 @@
//===----- CXXABI.h - Interface to C++ ABIs ---------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index ddb350e72bbd..ecf451b175af 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -1,9 +1,8 @@
//===- CXXInheritance.cpp - C++ Inheritance -------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -487,6 +486,21 @@ bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
return false;
}
+bool CXXRecordDecl::FindOMPMapperMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ DeclarationName Name) {
+ RecordDecl *BaseRecord =
+ Specifier->getType()->castAs<RecordType>()->getDecl();
+
+ for (Path.Decls = BaseRecord->lookup(Name); !Path.Decls.empty();
+ Path.Decls = Path.Decls.slice(1)) {
+ if (Path.Decls.front()->isInIdentifierNamespace(IDNS_OMPMapper))
+ return true;
+ }
+
+ return false;
+}
+
bool CXXRecordDecl::
FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
@@ -540,8 +554,7 @@ void OverridingMethods::add(unsigned OverriddenSubobject,
UniqueVirtualMethod Overriding) {
SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
= Overrides[OverriddenSubobject];
- if (std::find(SubobjectOverrides.begin(), SubobjectOverrides.end(),
- Overriding) == SubobjectOverrides.end())
+ if (llvm::find(SubobjectOverrides, Overriding) == SubobjectOverrides.end())
SubobjectOverrides.push_back(Overriding);
}
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index 0d759e226c42..25339c7901e3 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -1,9 +1,8 @@
//===--- Comment.cpp - Comment AST node implementation --------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentBriefParser.cpp b/lib/AST/CommentBriefParser.cpp
index 5ec7586a475d..2b648cbb1d4b 100644
--- a/lib/AST/CommentBriefParser.cpp
+++ b/lib/AST/CommentBriefParser.cpp
@@ -1,9 +1,8 @@
//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
index 7378a7c3ac06..b306fcbb154f 100644
--- a/lib/AST/CommentCommandTraits.cpp
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -1,9 +1,8 @@
//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index c43275318dd7..19485f6018c0 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -1,9 +1,8 @@
//===--- CommentLexer.cpp -------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 7f70b95e9812..c7f8aa7e16a0 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -1,9 +1,8 @@
//===--- CommentParser.cpp - Doxygen comment parser -----------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 88588a7a89e6..067b3ae4222e 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -1,9 +1,8 @@
//===--- CommentSema.cpp - Doxygen comment semantic analysis --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/ComparisonCategories.cpp b/lib/AST/ComparisonCategories.cpp
index 87f51facc59b..ee4c1b0443a3 100644
--- a/lib/AST/ComparisonCategories.cpp
+++ b/lib/AST/ComparisonCategories.cpp
@@ -1,9 +1,8 @@
//===- ComparisonCategories.cpp - Three Way Comparison Data -----*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DataCollection.cpp b/lib/AST/DataCollection.cpp
index c2ecabe8e6f8..8e67c101dee1 100644
--- a/lib/AST/DataCollection.cpp
+++ b/lib/AST/DataCollection.cpp
@@ -1,9 +1,8 @@
//===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5536358b1ecf..21cf9da18a8b 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1,9 +1,8 @@
//===- Decl.cpp - Declaration AST Node Implementation ---------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -568,7 +567,14 @@ static bool isSingleLineLanguageLinkage(const Decl &D) {
return false;
}
-static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
+/// Determine whether D is declared in the purview of a named module.
+static bool isInModulePurview(const NamedDecl *D) {
+ if (auto *M = D->getOwningModule())
+ return M->isModulePurview();
+ return false;
+}
+
+static bool isExportedFromModuleInterfaceUnit(const NamedDecl *D) {
// FIXME: Handle isModulePrivate.
switch (D->getModuleOwnershipKind()) {
case Decl::ModuleOwnershipKind::Unowned:
@@ -576,8 +582,7 @@ static bool isExportedFromModuleIntefaceUnit(const NamedDecl *D) {
return false;
case Decl::ModuleOwnershipKind::Visible:
case Decl::ModuleOwnershipKind::VisibleWhenImported:
- if (auto *M = D->getOwningModule())
- return M->Kind == Module::ModuleInterfaceUnit;
+ return isInModulePurview(D);
}
llvm_unreachable("unexpected module ownership kind");
}
@@ -587,9 +592,8 @@ static LinkageInfo getInternalLinkageFor(const NamedDecl *D) {
// as "module-internal linkage", which means that they have internal linkage
// formally but can be indirectly accessed from outside the module via inline
// functions and templates defined within the module.
- if (auto *M = D->getOwningModule())
- if (M->Kind == Module::ModuleInterfaceUnit)
- return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
+ if (isInModulePurview(D))
+ return LinkageInfo(ModuleInternalLinkage, DefaultVisibility, false);
return LinkageInfo::internal();
}
@@ -599,15 +603,25 @@ static LinkageInfo getExternalLinkageFor(const NamedDecl *D) {
// - A name declared at namespace scope that does not have internal linkage
// by the previous rules and that is introduced by a non-exported
// declaration has module linkage.
- if (auto *M = D->getOwningModule())
- if (M->Kind == Module::ModuleInterfaceUnit)
- if (!isExportedFromModuleIntefaceUnit(
- cast<NamedDecl>(D->getCanonicalDecl())))
- return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
+ if (isInModulePurview(D) && !isExportedFromModuleInterfaceUnit(
+ cast<NamedDecl>(D->getCanonicalDecl())))
+ return LinkageInfo(ModuleLinkage, DefaultVisibility, false);
return LinkageInfo::external();
}
+static StorageClass getStorageClass(const Decl *D) {
+ if (auto *TD = dyn_cast<TemplateDecl>(D))
+ D = TD->getTemplatedDecl();
+ if (D) {
+ if (auto *VD = dyn_cast<VarDecl>(D))
+ return VD->getStorageClass();
+ if (auto *FD = dyn_cast<FunctionDecl>(D))
+ return FD->getStorageClass();
+ }
+ return SC_None;
+}
+
LinkageInfo
LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
LVComputationKind computation,
@@ -619,24 +633,28 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// C++ [basic.link]p3:
// A name having namespace scope (3.3.6) has internal linkage if it
// is the name of
- // - an object, reference, function or function template that is
- // explicitly declared static; or,
- // (This bullet corresponds to C99 6.2.2p3.)
+
+ if (getStorageClass(D->getCanonicalDecl()) == SC_Static) {
+ // - a variable, variable template, function, or function template
+ // that is explicitly declared static; or
+ // (This bullet corresponds to C99 6.2.2p3.)
+ return getInternalLinkageFor(D);
+ }
+
if (const auto *Var = dyn_cast<VarDecl>(D)) {
- // Explicitly declared static.
- if (Var->getStorageClass() == SC_Static)
- return getInternalLinkageFor(Var);
-
- // - a non-inline, non-volatile object or reference that is explicitly
- // declared const or constexpr and neither explicitly declared extern
- // nor previously declared to have external linkage; or (there is no
- // equivalent in C99)
- // The C++ modules TS adds "non-exported" to this list.
+ // - a non-template variable of non-volatile const-qualified type, unless
+ // - it is explicitly declared extern, or
+ // - it is inline or exported, or
+ // - it was previously declared and the prior declaration did not have
+ // internal linkage
+ // (There is no equivalent in C99.)
if (Context.getLangOpts().CPlusPlus &&
Var->getType().isConstQualified() &&
!Var->getType().isVolatileQualified() &&
!Var->isInline() &&
- !isExportedFromModuleIntefaceUnit(Var)) {
+ !isExportedFromModuleInterfaceUnit(Var) &&
+ !isa<VarTemplateSpecializationDecl>(Var) &&
+ !Var->getDescribedVarTemplate()) {
const VarDecl *PrevVar = Var->getPreviousDecl();
if (PrevVar)
return getLVForDecl(PrevVar, computation);
@@ -656,14 +674,6 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
if (PrevVar->getStorageClass() == SC_Static)
return getInternalLinkageFor(Var);
}
- } else if (const FunctionDecl *Function = D->getAsFunction()) {
- // C++ [temp]p4:
- // A non-member function template can have internal linkage; any
- // other template name shall have external linkage.
-
- // Explicitly declared static.
- if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
- return getInternalLinkageFor(Function);
} else if (const auto *IFD = dyn_cast<IndirectFieldDecl>(D)) {
// - a data member of an anonymous union.
const VarDecl *VD = IFD->getVarDecl();
@@ -672,6 +682,8 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
}
assert(!isa<FieldDecl>(D) && "Didn't expect a FieldDecl!");
+ // FIXME: This gives internal linkage to names that should have no linkage
+ // (those not covered by [basic.link]p6).
if (D->isInAnonymousNamespace()) {
const auto *Var = dyn_cast<VarDecl>(D);
const auto *Func = dyn_cast<FunctionDecl>(D);
@@ -731,10 +743,20 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
// C++ [basic.link]p4:
- // A name having namespace scope has external linkage if it is the
- // name of
+ // A name having namespace scope that has not been given internal linkage
+ // above and that is the name of
+ // [...bullets...]
+ // has its linkage determined as follows:
+ // - if the enclosing namespace has internal linkage, the name has
+ // internal linkage; [handled above]
+ // - otherwise, if the declaration of the name is attached to a named
+ // module and is not exported, the name has module linkage;
+ // - otherwise, the name has external linkage.
+ // LV is currently set up to handle the last two bullets.
//
- // - an object or reference, unless it has internal linkage; or
+ // The bullets are:
+
+ // - a variable; or
if (const auto *Var = dyn_cast<VarDecl>(D)) {
// GCC applies the following optimization to variables and static
// data members, but not to functions:
@@ -780,7 +802,7 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
mergeTemplateLV(LV, spec, computation);
}
- // - a function, unless it has internal linkage; or
+ // - a function; or
} else if (const auto *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
// type unless it has C linkage (see comment above about variables
@@ -834,7 +856,8 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
mergeTemplateLV(LV, spec, computation);
}
- // - an enumerator belonging to an enumeration with external linkage;
+ // FIXME: This is not part of the C++ standard any more.
+ // - an enumerator belonging to an enumeration with external linkage; or
} else if (isa<EnumConstantDecl>(D)) {
LinkageInfo EnumLV = getLVForDecl(cast<NamedDecl>(D->getDeclContext()),
computation);
@@ -842,16 +865,16 @@ LinkageComputer::getLVForNamespaceScopeDecl(const NamedDecl *D,
return LinkageInfo::none();
LV.merge(EnumLV);
- // - a template, unless it is a function template that has
- // internal linkage (Clause 14);
+ // - a template
} else if (const auto *temp = dyn_cast<TemplateDecl>(D)) {
bool considerVisibility = !hasExplicitVisibilityAlready(computation);
LinkageInfo tempLV =
getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
LV.mergeMaybeWithVisibility(tempLV, considerVisibility);
- // - a namespace (7.3), unless it is declared within an unnamed
- // namespace.
+ // An unnamed namespace or a namespace declared directly or indirectly
+ // within an unnamed namespace has internal linkage. All other namespaces
+ // have external linkage.
//
// We handled names in anonymous namespaces above.
} else if (isa<NamespaceDecl>(D)) {
@@ -1508,6 +1531,11 @@ Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
}
return InternalLinkage ? M->Parent : nullptr;
}
+
+ case Module::PrivateModuleFragment:
+ // The private module fragment is part of its containing module for linkage
+ // purposes.
+ return M->Parent;
}
llvm_unreachable("unknown module kind");
@@ -1532,10 +1560,16 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
const DeclContext *Ctx = getDeclContext();
- // For ObjC methods, look through categories and use the interface as context.
+ // For ObjC methods and properties, look through categories and use the
+ // interface as context.
if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
if (auto *ID = MD->getClassInterface())
Ctx = ID;
+ if (auto *PD = dyn_cast<ObjCPropertyDecl>(this)) {
+ if (auto *MD = PD->getGetterMethodDecl())
+ if (auto *ID = MD->getClassInterface())
+ Ctx = ID;
+ }
if (Ctx->isFunctionOrMethod()) {
printName(OS);
@@ -2211,12 +2245,16 @@ void VarDecl::setInit(Expr *I) {
Init = I;
}
-bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
+bool VarDecl::mightBeUsableInConstantExpressions(ASTContext &C) const {
const LangOptions &Lang = C.getLangOpts();
if (!Lang.CPlusPlus)
return false;
+ // Function parameters are never usable in constant expressions.
+ if (isa<ParmVarDecl>(this))
+ return false;
+
// In C++11, any variable of reference type can be used in a constant
// expression if it is initialized by a constant expression.
if (Lang.CPlusPlus11 && getType()->isReferenceType())
@@ -2238,6 +2276,22 @@ bool VarDecl::isUsableInConstantExpressions(ASTContext &C) const {
return Lang.CPlusPlus11 && isConstexpr();
}
+bool VarDecl::isUsableInConstantExpressions(ASTContext &Context) const {
+ // C++2a [expr.const]p3:
+ // A variable is usable in constant expressions after its initializing
+ // declaration is encountered...
+ const VarDecl *DefVD = nullptr;
+ const Expr *Init = getAnyInitializer(DefVD);
+ if (!Init || Init->isValueDependent() || getType()->isDependentType())
+ return false;
+ // ... if it is a constexpr variable, or it is of reference type or of
+ // const-qualified integral or enumeration type, ...
+ if (!DefVD->mightBeUsableInConstantExpressions(Context))
+ return false;
+ // ... and its initializer is a constant initializer.
+ return DefVD->checkInitIsICE();
+}
+
/// Convert the initializer for this declaration to the elaborated EvaluatedStmt
/// form, which contains extra information on the evaluated value of the
/// initializer.
@@ -2268,7 +2322,7 @@ APValue *VarDecl::evaluateValue(
// first time it is evaluated. FIXME: The notes won't always be emitted the
// first time we try evaluation, so might not be produced at all.
if (Eval->WasEvaluated)
- return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
+ return Eval->Evaluated.isAbsent() ? nullptr : &Eval->Evaluated;
const auto *Init = cast<Expr>(Eval->Value);
assert(!Init->isValueDependent());
@@ -2363,6 +2417,10 @@ bool VarDecl::checkInitIsICE() const {
return Eval->IsICE;
}
+bool VarDecl::isParameterPack() const {
+ return isa<PackExpansionType>(getType());
+}
+
template<typename DeclT>
static DeclT *getDefinitionOrSelf(DeclT *D) {
assert(D);
@@ -2380,48 +2438,61 @@ bool VarDecl::isNonEscapingByref() const {
}
VarDecl *VarDecl::getTemplateInstantiationPattern() const {
- // If it's a variable template specialization, find the template or partial
- // specialization from which it was instantiated.
- if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(this)) {
- auto From = VDTemplSpec->getInstantiatedFrom();
- if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
- while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) {
- if (NewVTD->isMemberSpecialization())
- break;
- VTD = NewVTD;
- }
- return getDefinitionOrSelf(VTD->getTemplatedDecl());
- }
- if (auto *VTPSD =
- From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
- while (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) {
- if (NewVTPSD->isMemberSpecialization())
- break;
- VTPSD = NewVTPSD;
- }
- return getDefinitionOrSelf<VarDecl>(VTPSD);
- }
- }
+ const VarDecl *VD = this;
- if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+ // If this is an instantiated member, walk back to the template from which
+ // it was instantiated.
+ if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo()) {
if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
- VarDecl *VD = getInstantiatedFromStaticDataMember();
+ VD = VD->getInstantiatedFromStaticDataMember();
while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
VD = NewVD;
- return getDefinitionOrSelf(VD);
}
}
- if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) {
- while (VarTemplate->getInstantiatedFromMemberTemplate()) {
- if (VarTemplate->isMemberSpecialization())
+ // If it's an instantiated variable template specialization, find the
+ // template or partial specialization from which it was instantiated.
+ if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(VD)) {
+ if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) {
+ auto From = VDTemplSpec->getInstantiatedFrom();
+ if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
+ while (!VTD->isMemberSpecialization()) {
+ auto *NewVTD = VTD->getInstantiatedFromMemberTemplate();
+ if (!NewVTD)
+ break;
+ VTD = NewVTD;
+ }
+ return getDefinitionOrSelf(VTD->getTemplatedDecl());
+ }
+ if (auto *VTPSD =
+ From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ while (!VTPSD->isMemberSpecialization()) {
+ auto *NewVTPSD = VTPSD->getInstantiatedFromMember();
+ if (!NewVTPSD)
+ break;
+ VTPSD = NewVTPSD;
+ }
+ return getDefinitionOrSelf<VarDecl>(VTPSD);
+ }
+ }
+ }
+
+ // If this is the pattern of a variable template, find where it was
+ // instantiated from. FIXME: Is this necessary?
+ if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) {
+ while (!VarTemplate->isMemberSpecialization()) {
+ auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate();
+ if (!NewVT)
break;
- VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
+ VarTemplate = NewVT;
}
return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
}
- return nullptr;
+
+ if (VD == this)
+ return nullptr;
+ return getDefinitionOrSelf(const_cast<VarDecl*>(VD));
}
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
@@ -2441,6 +2512,17 @@ TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
return TSK_Undeclared;
}
+TemplateSpecializationKind
+VarDecl::getTemplateSpecializationKindForInstantiation() const {
+ if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
+ return MSI->getTemplateSpecializationKind();
+
+ if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
+ return Spec->getSpecializationKind();
+
+ return TSK_Undeclared;
+}
+
SourceLocation VarDecl::getPointOfInstantiation() const {
if (const auto *Spec = dyn_cast<VarTemplateSpecializationDecl>(this))
return Spec->getPointOfInstantiation();
@@ -2501,15 +2583,14 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
if (VarTemplateSpecializationDecl *Spec =
dyn_cast<VarTemplateSpecializationDecl>(this)) {
Spec->setSpecializationKind(TSK);
- if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
+ if (TSK != TSK_ExplicitSpecialization &&
+ PointOfInstantiation.isValid() &&
Spec->getPointOfInstantiation().isInvalid()) {
Spec->setPointOfInstantiation(PointOfInstantiation);
if (ASTMutationListener *L = getASTContext().getASTMutationListener())
L->InstantiationRequested(this);
}
- }
-
- if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
+ } else if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {
MSI->setTemplateSpecializationKind(TSK);
if (TSK != TSK_ExplicitSpecialization && PointOfInstantiation.isValid() &&
MSI->getPointOfInstantiation().isInvalid()) {
@@ -2626,10 +2707,6 @@ bool ParmVarDecl::hasDefaultArg() const {
!Init.isNull();
}
-bool ParmVarDecl::isParameterPack() const {
- return isa<PackExpansionType>(getType());
-}
-
void ParmVarDecl::setParameterIndexLarge(unsigned parameterIndex) {
getASTContext().setParameterIndex(this, parameterIndex);
ParmVarDeclBits.ParameterIndex = ParameterIndexSentinel;
@@ -2647,7 +2724,8 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T,
TypeSourceInfo *TInfo, StorageClass S,
- bool isInlineSpecified, bool isConstexprSpecified)
+ bool isInlineSpecified,
+ ConstexprSpecKind ConstexprKind)
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK), redeclarable_base(C), ODRHash(0),
@@ -2656,7 +2734,6 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
FunctionDeclBits.SClass = S;
FunctionDeclBits.IsInline = isInlineSpecified;
FunctionDeclBits.IsInlineSpecified = isInlineSpecified;
- FunctionDeclBits.IsExplicitSpecified = false;
FunctionDeclBits.IsVirtualAsWritten = false;
FunctionDeclBits.IsPure = false;
FunctionDeclBits.HasInheritedPrototype = false;
@@ -2668,7 +2745,7 @@ FunctionDecl::FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC,
FunctionDeclBits.IsExplicitlyDefaulted = false;
FunctionDeclBits.HasImplicitReturnZero = false;
FunctionDeclBits.IsLateTemplateParsed = false;
- FunctionDeclBits.IsConstexpr = isConstexprSpecified;
+ FunctionDeclBits.ConstexprKind = ConstexprKind;
FunctionDeclBits.InstantiationIsPending = false;
FunctionDeclBits.UsesSEHTry = false;
FunctionDeclBits.HasSkippedBody = false;
@@ -2904,6 +2981,8 @@ bool FunctionDecl::isExternC() const {
}
bool FunctionDecl::isInExternCContext() const {
+ if (hasAttr<OpenCLKernelAttr>())
+ return true;
return getLexicalDeclContext()->isExternCContext();
}
@@ -2982,16 +3061,20 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
FunctionDecl *FunctionDecl::getCanonicalDecl() { return getFirstDecl(); }
-/// Returns a value indicating whether this function
-/// corresponds to a builtin function.
+/// Returns a value indicating whether this function corresponds to a builtin
+/// function.
///
-/// The function corresponds to a built-in function if it is
-/// declared at translation scope or within an extern "C" block and
-/// its name matches with the name of a builtin. The returned value
-/// will be 0 for functions that do not correspond to a builtin, a
-/// value of type \c Builtin::ID if in the target-independent range
-/// \c [1,Builtin::First), or a target-specific builtin value.
-unsigned FunctionDecl::getBuiltinID() const {
+/// The function corresponds to a built-in function if it is declared at
+/// translation scope or within an extern "C" block and its name matches with
+/// the name of a builtin. The returned value will be 0 for functions that do
+/// not correspond to a builtin, a value of type \c Builtin::ID if in the
+/// target-independent range \c [1,Builtin::First), or a target-specific builtin
+/// value.
+///
+/// \param ConsiderWrapperFunctions If true, we should consider wrapper
+/// functions as their wrapped builtins. This shouldn't be done in general, but
+/// it's useful in Sema to diagnose calls to wrappers based on their semantics.
+unsigned FunctionDecl::getBuiltinID(bool ConsiderWrapperFunctions) const {
if (!getIdentifier())
return 0;
@@ -3019,7 +3102,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// If the function is marked "overloadable", it has a different mangled name
// and is not the C library function.
- if (hasAttr<OverloadableAttr>())
+ if (!ConsiderWrapperFunctions && hasAttr<OverloadableAttr>())
return 0;
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -3030,7 +3113,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// function or whether it just has the same name.
// If this is a static function, it's not a builtin.
- if (getStorageClass() == SC_Static)
+ if (!ConsiderWrapperFunctions && getStorageClass() == SC_Static)
return 0;
// OpenCL v1.2 s6.9.f - The library functions defined in
@@ -3337,7 +3420,13 @@ FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
}
MemberSpecializationInfo *FunctionDecl::getMemberSpecializationInfo() const {
- return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>();
+ if (auto *MSI =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
+ return MSI;
+ if (auto *FTSI = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>())
+ return FTSI->getMemberSpecializationInfo();
+ return nullptr;
}
void
@@ -3356,6 +3445,8 @@ FunctionTemplateDecl *FunctionDecl::getDescribedFunctionTemplate() const {
}
void FunctionDecl::setDescribedFunctionTemplate(FunctionTemplateDecl *Template) {
+ assert(TemplateOrSpecialization.isNull() &&
+ "Member function is already a specialization");
TemplateOrSpecialization = Template;
}
@@ -3364,19 +3455,15 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
if (isInvalidDecl())
return false;
- switch (getTemplateSpecializationKind()) {
+ switch (getTemplateSpecializationKindForInstantiation()) {
case TSK_Undeclared:
case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
return false;
case TSK_ImplicitInstantiation:
return true;
- // It is possible to instantiate TSK_ExplicitSpecialization kind
- // if the FunctionDecl has a class scope specialization pattern.
- case TSK_ExplicitSpecialization:
- return getClassScopeSpecializationPattern() != nullptr;
-
case TSK_ExplicitInstantiationDeclaration:
// Handled below.
break;
@@ -3399,26 +3486,12 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
}
bool FunctionDecl::isTemplateInstantiation() const {
- switch (getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ExplicitSpecialization:
- return false;
- case TSK_ImplicitInstantiation:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- return true;
- }
- llvm_unreachable("All TSK values handled.");
+ // FIXME: Remove this, it's not clear what it means. (Which template
+ // specialization kind?)
+ return clang::isTemplateInstantiation(getTemplateSpecializationKind());
}
FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
- // Handle class scope explicit specialization special case.
- if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
- if (auto *Spec = getClassScopeSpecializationPattern())
- return getDefinitionOrSelf(Spec);
- return nullptr;
- }
-
// If this is a generic lambda call operator specialization, its
// instantiation pattern is always its primary template's pattern
// even if its primary template was instantiated from another
@@ -3434,21 +3507,28 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl());
}
+ if (MemberSpecializationInfo *Info = getMemberSpecializationInfo()) {
+ if (!clang::isTemplateInstantiation(Info->getTemplateSpecializationKind()))
+ return nullptr;
+ return getDefinitionOrSelf(cast<FunctionDecl>(Info->getInstantiatedFrom()));
+ }
+
+ if (!clang::isTemplateInstantiation(getTemplateSpecializationKind()))
+ return nullptr;
+
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
- while (Primary->getInstantiatedFromMemberTemplate()) {
- // If we have hit a point where the user provided a specialization of
- // this template, we're done looking.
- if (Primary->isMemberSpecialization())
+ // If we hit a point where the user provided a specialization of this
+ // template, we're done looking.
+ while (!Primary->isMemberSpecialization()) {
+ auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate();
+ if (!NewPrimary)
break;
- Primary = Primary->getInstantiatedFromMemberTemplate();
+ Primary = NewPrimary;
}
return getDefinitionOrSelf(Primary->getTemplatedDecl());
}
- if (auto *MFD = getInstantiatedFromMemberFunction())
- return getDefinitionOrSelf(MFD);
-
return nullptr;
}
@@ -3456,15 +3536,11 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
if (FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
- return Info->Template.getPointer();
+ return Info->getTemplate();
}
return nullptr;
}
-FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
- return getASTContext().getClassScopeSpecializationPattern(this);
-}
-
FunctionTemplateSpecializationInfo *
FunctionDecl::getTemplateSpecializationInfo() const {
return TemplateOrSpecialization
@@ -3499,15 +3575,19 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &C,
TemplateSpecializationKind TSK,
const TemplateArgumentListInfo *TemplateArgsAsWritten,
SourceLocation PointOfInstantiation) {
+ assert((TemplateOrSpecialization.isNull() ||
+ TemplateOrSpecialization.is<MemberSpecializationInfo *>()) &&
+ "Member function is already a specialization");
assert(TSK != TSK_Undeclared &&
"Must specify the type of function template specialization");
- FunctionTemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
- if (!Info)
- Info = FunctionTemplateSpecializationInfo::Create(C, this, Template, TSK,
- TemplateArgs,
- TemplateArgsAsWritten,
- PointOfInstantiation);
+ assert((TemplateOrSpecialization.isNull() ||
+ TSK == TSK_ExplicitSpecialization) &&
+ "Member specialization must be an explicit specialization");
+ FunctionTemplateSpecializationInfo *Info =
+ FunctionTemplateSpecializationInfo::Create(
+ C, this, Template, TSK, TemplateArgs, TemplateArgsAsWritten,
+ PointOfInstantiation,
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>());
TemplateOrSpecialization = Info;
Template->addSpecialization(Info, InsertPos);
}
@@ -3558,14 +3638,47 @@ DependentFunctionTemplateSpecializationInfo(const UnresolvedSetImpl &Ts,
TemplateSpecializationKind FunctionDecl::getTemplateSpecializationKind() const {
// For a function template specialization, query the specialization
// information object.
- FunctionTemplateSpecializationInfo *FTSInfo
- = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
- if (FTSInfo)
+ if (FunctionTemplateSpecializationInfo *FTSInfo =
+ TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>())
+ return FTSInfo->getTemplateSpecializationKind();
+
+ if (MemberSpecializationInfo *MSInfo =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
+ return MSInfo->getTemplateSpecializationKind();
+
+ return TSK_Undeclared;
+}
+
+TemplateSpecializationKind
+FunctionDecl::getTemplateSpecializationKindForInstantiation() const {
+ // This is the same as getTemplateSpecializationKind(), except that for a
+ // function that is both a function template specialization and a member
+ // specialization, we prefer the member specialization information. Eg:
+ //
+ // template<typename T> struct A {
+ // template<typename U> void f() {}
+ // template<> void f<int>() {}
+ // };
+ //
+ // For A<int>::f<int>():
+ // * getTemplateSpecializationKind() will return TSK_ExplicitSpecialization
+ // * getTemplateSpecializationKindForInstantiation() will return
+ // TSK_ImplicitInstantiation
+ //
+ // This reflects the facts that A<int>::f<int> is an explicit specialization
+ // of A<int>::f, and that A<int>::f<int> should be implicitly instantiated
+ // from A::f<int> if a definition is needed.
+ if (FunctionTemplateSpecializationInfo *FTSInfo =
+ TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo *>()) {
+ if (auto *MSInfo = FTSInfo->getMemberSpecializationInfo())
+ return MSInfo->getTemplateSpecializationKind();
return FTSInfo->getTemplateSpecializationKind();
+ }
- MemberSpecializationInfo *MSInfo
- = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
- if (MSInfo)
+ if (MemberSpecializationInfo *MSInfo =
+ TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo *>())
return MSInfo->getTemplateSpecializationKind();
return TSK_Undeclared;
@@ -3673,6 +3786,10 @@ unsigned FunctionDecl::getMemoryFunctionKind() const {
case Builtin::BImemcmp:
return Builtin::BImemcmp;
+ case Builtin::BI__builtin_bcmp:
+ case Builtin::BIbcmp:
+ return Builtin::BIbcmp;
+
case Builtin::BI__builtin_strncpy:
case Builtin::BI__builtin___strncpy_chk:
case Builtin::BIstrncpy:
@@ -3713,6 +3830,8 @@ unsigned FunctionDecl::getMemoryFunctionKind() const {
return Builtin::BImemmove;
else if (FnInfo->isStr("memcmp"))
return Builtin::BImemcmp;
+ else if (FnInfo->isStr("bcmp"))
+ return Builtin::BIbcmp;
else if (FnInfo->isStr("strncpy"))
return Builtin::BIstrncpy;
else if (FnInfo->isStr("strncmp"))
@@ -3794,6 +3913,39 @@ bool FieldDecl::isZeroLengthBitField(const ASTContext &Ctx) const {
getBitWidthValue(Ctx) == 0;
}
+bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
+ if (isZeroLengthBitField(Ctx))
+ return true;
+
+ // C++2a [intro.object]p7:
+ // An object has nonzero size if it
+ // -- is not a potentially-overlapping subobject, or
+ if (!hasAttr<NoUniqueAddressAttr>())
+ return false;
+
+ // -- is not of class type, or
+ const auto *RT = getType()->getAs<RecordType>();
+ if (!RT)
+ return false;
+ const RecordDecl *RD = RT->getDecl()->getDefinition();
+ if (!RD) {
+ assert(isInvalidDecl() && "valid field has incomplete type");
+ return false;
+ }
+
+ // -- [has] virtual member functions or virtual base classes, or
+ // -- has subobjects of nonzero size or bit-fields of nonzero length
+ const auto *CXXRD = cast<CXXRecordDecl>(RD);
+ if (!CXXRD->isEmpty())
+ return false;
+
+ // Otherwise, [...] the circumstances under which the object has zero size
+ // are implementation-defined.
+ // FIXME: This might be Itanium ABI specific; we don't yet know what the MS
+ // ABI will do.
+ return true;
+}
+
unsigned FieldDecl::getFieldIndex() const {
const FieldDecl *Canonical = getCanonicalDecl();
if (Canonical != this)
@@ -4100,6 +4252,9 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
setNonTrivialToPrimitiveDefaultInitialize(false);
setNonTrivialToPrimitiveCopy(false);
setNonTrivialToPrimitiveDestroy(false);
+ setHasNonTrivialToPrimitiveDefaultInitializeCUnion(false);
+ setHasNonTrivialToPrimitiveDestructCUnion(false);
+ setHasNonTrivialToPrimitiveCopyCUnion(false);
setParamDestroyedInCallee(false);
setArgPassingRestrictions(APK_CanPassInRegs);
}
@@ -4260,6 +4415,7 @@ BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
setBlockMissingReturnType(true);
setIsConversionFromLambda(false);
setDoesNotEscape(false);
+ setCanAvoidCopyToHeap(false);
}
void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
@@ -4422,13 +4578,12 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
- StorageClass SC,
- bool isInlineSpecified,
+ StorageClass SC, bool isInlineSpecified,
bool hasWrittenPrototype,
- bool isConstexprSpecified) {
+ ConstexprSpecKind ConstexprKind) {
FunctionDecl *New =
new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
- SC, isInlineSpecified, isConstexprSpecified);
+ SC, isInlineSpecified, ConstexprKind);
New->setHasWrittenPrototype(hasWrittenPrototype);
return New;
}
@@ -4436,7 +4591,7 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
DeclarationNameInfo(), QualType(), nullptr,
- SC_None, false, false);
+ SC_None, false, CSK_unspecified);
}
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index b83082e9eb08..fd80e1532eb5 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1,9 +1,8 @@
//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -209,8 +208,8 @@ bool Decl::isTemplateParameterPack() const {
}
bool Decl::isParameterPack() const {
- if (const auto *Parm = dyn_cast<ParmVarDecl>(this))
- return Parm->isParameterPack();
+ if (const auto *Var = dyn_cast<VarDecl>(this))
+ return Var->isParameterPack();
return isTemplateParameterPack();
}
@@ -355,7 +354,8 @@ bool Decl::isInAnonymousNamespace() const {
}
bool Decl::isInStdNamespace() const {
- return getDeclContext()->isStdNamespace();
+ const DeclContext *DC = getDeclContext();
+ return DC && DC->isStdNamespace();
}
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
@@ -431,22 +431,6 @@ bool Decl::isReferenced() const {
return false;
}
-bool Decl::isExported() const {
- if (isModulePrivate())
- return false;
- // Namespaces are always exported.
- if (isa<TranslationUnitDecl>(this) || isa<NamespaceDecl>(this))
- return true;
- // Otherwise, this is a strictly lexical check.
- for (auto *DC = getLexicalDeclContext(); DC; DC = DC->getLexicalParent()) {
- if (cast<Decl>(DC)->isModulePrivate())
- return false;
- if (isa<ExportDecl>(DC))
- return true;
- }
- return false;
-}
-
ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
const Decl *Definition = nullptr;
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(this)) {
@@ -726,6 +710,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case Binding:
case NonTypeTemplateParm:
case VarTemplate:
+ case Concept:
// These (C++-only) declarations are found by redeclaration lookup for
// tag types, so we include them in the tag namespace.
return IDNS_Ordinary | IDNS_Tag;
@@ -781,6 +766,9 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case OMPDeclareReduction:
return IDNS_OMPReduction;
+ case OMPDeclareMapper:
+ return IDNS_OMPMapper;
+
// Never have names.
case Friend:
case FriendTemplate:
@@ -810,6 +798,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategoryImpl:
case Import:
case OMPThreadPrivate:
+ case OMPAllocate:
case OMPRequires:
case OMPCapturedExpr:
case Empty:
@@ -932,6 +921,7 @@ bool Decl::AccessDeclContextSanity() const {
if (isa<TranslationUnitDecl>(this) ||
isa<TemplateTypeParmDecl>(this) ||
isa<NonTypeTemplateParmDecl>(this) ||
+ !getDeclContext() ||
!isa<CXXRecordDecl>(getDeclContext()) ||
isInvalidDecl() ||
isa<StaticAssertDecl>(this) ||
@@ -969,6 +959,8 @@ const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
if (Ty->isFunctionPointerType())
Ty = Ty->getAs<PointerType>()->getPointeeType();
+ else if (Ty->isFunctionReferenceType())
+ Ty = Ty->getAs<ReferenceType>()->getPointeeType();
else if (BlocksToo && Ty->isBlockPointerType())
Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
@@ -1054,6 +1046,18 @@ DeclContext *DeclContext::getLookupParent() {
return getParent();
}
+const BlockDecl *DeclContext::getInnermostBlockDecl() const {
+ const DeclContext *Ctx = this;
+
+ do {
+ if (Ctx->isClosure())
+ return cast<BlockDecl>(Ctx);
+ Ctx = Ctx->getParent();
+ } while (Ctx);
+
+ return nullptr;
+}
+
bool DeclContext::isInlineNamespace() const {
return isNamespace() &&
cast<NamespaceDecl>(this)->isInline();
@@ -1164,6 +1168,7 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::Block:
case Decl::Captured:
case Decl::OMPDeclareReduction:
+ case Decl::OMPDeclareMapper:
// There is only one DeclContext for these entities.
return this;
@@ -1175,13 +1180,15 @@ DeclContext *DeclContext::getPrimaryContext() {
return this;
case Decl::ObjCInterface:
- if (auto *Def = cast<ObjCInterfaceDecl>(this)->getDefinition())
- return Def;
+ if (auto *OID = dyn_cast<ObjCInterfaceDecl>(this))
+ if (auto *Def = OID->getDefinition())
+ return Def;
return this;
case Decl::ObjCProtocol:
- if (auto *Def = cast<ObjCProtocolDecl>(this)->getDefinition())
- return Def;
+ if (auto *OPD = dyn_cast<ObjCProtocolDecl>(this))
+ if (auto *Def = OPD->getDefinition())
+ return Def;
return this;
case Decl::ObjCCategory:
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 31ffeb0dcd1e..59710a55498f 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1,9 +1,8 @@
//===- DeclCXX.cpp - C++ Declaration AST Node Implementation --------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -606,14 +605,19 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
// that sure looks like a wording bug.
// -- If X is a non-union class type with a non-static data member
- // [recurse to] the first non-static data member of X
+ // [recurse to each field] that is either of zero size or is the
+ // first non-static data member of X
// -- If X is a union type, [recurse to union members]
+ bool IsFirstField = true;
for (auto *FD : X->fields()) {
// FIXME: Should we really care about the type of the first non-static
// data member of a non-union if there are preceding unnamed bit-fields?
if (FD->isUnnamedBitfield())
continue;
+ if (!IsFirstField && !FD->isZeroSize(Ctx))
+ continue;
+
// -- If X is n array type, [visit the element type]
QualType T = Ctx.getBaseElementType(FD->getType());
if (auto *RD = T->getAsCXXRecordDecl())
@@ -621,7 +625,7 @@ bool CXXRecordDecl::hasSubobjectAtOffsetZeroOfEmptyBaseType(
return true;
if (!X->isUnion())
- break;
+ IsFirstField = false;
}
}
@@ -641,7 +645,8 @@ bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const {
// C++17 [expr.prim.lambda]p21:
// The closure type associated with a lambda-expression has no default
// constructor and a deleted copy assignment operator.
- if (getLambdaCaptureDefault() != LCD_None)
+ if (getLambdaCaptureDefault() != LCD_None ||
+ getLambdaData().NumCaptures != 0)
return false;
return getASTContext().getLangOpts().CPlusPlus2a;
}
@@ -992,6 +997,17 @@ void CXXRecordDecl::addedMember(Decl *D) {
setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs);
Data.HasIrrelevantDestructor = false;
+
+ if (isUnion()) {
+ data().DefaultedCopyConstructorIsDeleted = true;
+ data().DefaultedMoveConstructorIsDeleted = true;
+ data().DefaultedMoveAssignmentIsDeleted = true;
+ data().DefaultedDestructorIsDeleted = true;
+ data().NeedOverloadResolutionForCopyConstructor = true;
+ data().NeedOverloadResolutionForMoveConstructor = true;
+ data().NeedOverloadResolutionForMoveAssignment = true;
+ data().NeedOverloadResolutionForDestructor = true;
+ }
} else if (!Context.getLangOpts().ObjCAutoRefCount) {
setHasObjectMember(true);
}
@@ -1058,6 +1074,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (T->isReferenceType())
data().DefaultedMoveAssignmentIsDeleted = true;
+ // Bitfields of length 0 are also zero-sized, but we already bailed out for
+ // those because they are always unnamed.
+ bool IsZeroSize = Field->isZeroSize(Context);
+
if (const auto *RecordTy = T->getAs<RecordType>()) {
auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
if (FieldRec->getDefinition()) {
@@ -1173,7 +1193,8 @@ void CXXRecordDecl::addedMember(Decl *D) {
// A standard-layout class is a class that:
// [...]
// -- has no element of the set M(S) of types as a base class.
- if (data().IsStandardLayout && (isUnion() || IsFirstField) &&
+ if (data().IsStandardLayout &&
+ (isUnion() || IsFirstField || IsZeroSize) &&
hasSubobjectAtOffsetZeroOfEmptyBaseType(Context, FieldRec))
data().IsStandardLayout = false;
@@ -1255,8 +1276,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
}
// C++14 [meta.unary.prop]p4:
- // T is a class type [...] with [...] no non-static data members
- data().Empty = false;
+ // T is a class type [...] with [...] no non-static data members other
+ // than subobjects of zero size
+ if (data().Empty && !IsZeroSize)
+ data().Empty = false;
}
// Handle using declarations of conversion functions.
@@ -1411,13 +1434,28 @@ void CXXRecordDecl::getCaptureFields(
TemplateParameterList *
CXXRecordDecl::getGenericLambdaTemplateParameterList() const {
- if (!isLambda()) return nullptr;
+ if (!isGenericLambda()) return nullptr;
CXXMethodDecl *CallOp = getLambdaCallOperator();
if (FunctionTemplateDecl *Tmpl = CallOp->getDescribedFunctionTemplate())
return Tmpl->getTemplateParameters();
return nullptr;
}
+ArrayRef<NamedDecl *>
+CXXRecordDecl::getLambdaExplicitTemplateParameters() const {
+ TemplateParameterList *List = getGenericLambdaTemplateParameterList();
+ if (!List)
+ return {};
+
+ assert(std::is_partitioned(List->begin(), List->end(),
+ [](const NamedDecl *D) { return !D->isImplicit(); })
+ && "Explicit template params should be ordered before implicit ones");
+
+ const auto ExplicitEnd = llvm::partition_point(
+ *List, [](const NamedDecl *D) { return !D->isImplicit(); });
+ return llvm::makeArrayRef(List->begin(), ExplicitEnd);
+}
+
Decl *CXXRecordDecl::getLambdaContextDecl() const {
assert(isLambda() && "Not a lambda closure type!");
ExternalASTSource *Source = getParentASTContext().getExternalSource();
@@ -1586,8 +1624,8 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {
for (unsigned I = 0, E = Convs.size(); I != E; ++I) {
if (Convs[I].getDecl() == ConvDecl) {
Convs.erase(I);
- assert(std::find(Convs.begin(), Convs.end(), ConvDecl) == Convs.end()
- && "conversion was found multiple times in unresolved set");
+ assert(llvm::find(Convs, ConvDecl) == Convs.end() &&
+ "conversion was found multiple times in unresolved set");
return;
}
}
@@ -1852,19 +1890,47 @@ bool CXXRecordDecl::mayBeAbstract() const {
void CXXDeductionGuideDecl::anchor() {}
+bool ExplicitSpecifier::isEquivalent(const ExplicitSpecifier Other) const {
+ if ((getKind() != Other.getKind() ||
+ getKind() == ExplicitSpecKind::Unresolved)) {
+ if (getKind() == ExplicitSpecKind::Unresolved &&
+ Other.getKind() == ExplicitSpecKind::Unresolved) {
+ ODRHash SelfHash, OtherHash;
+ SelfHash.AddStmt(getExpr());
+ OtherHash.AddStmt(Other.getExpr());
+ return SelfHash.CalculateHash() == OtherHash.CalculateHash();
+ } else
+ return false;
+ }
+ return true;
+}
+
+ExplicitSpecifier ExplicitSpecifier::getFromDecl(FunctionDecl *Function) {
+ switch (Function->getDeclKind()) {
+ case Decl::Kind::CXXConstructor:
+ return cast<CXXConstructorDecl>(Function)->getExplicitSpecifier();
+ case Decl::Kind::CXXConversion:
+ return cast<CXXConversionDecl>(Function)->getExplicitSpecifier();
+ case Decl::Kind::CXXDeductionGuide:
+ return cast<CXXDeductionGuideDecl>(Function)->getExplicitSpecifier();
+ default:
+ return {};
+ }
+}
+
CXXDeductionGuideDecl *CXXDeductionGuideDecl::Create(
- ASTContext &C, DeclContext *DC, SourceLocation StartLoc, bool IsExplicit,
- const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- SourceLocation EndLocation) {
- return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, IsExplicit,
- NameInfo, T, TInfo, EndLocation);
+ ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ ExplicitSpecifier ES, const DeclarationNameInfo &NameInfo, QualType T,
+ TypeSourceInfo *TInfo, SourceLocation EndLocation) {
+ return new (C, DC) CXXDeductionGuideDecl(C, DC, StartLoc, ES, NameInfo, T,
+ TInfo, EndLocation);
}
CXXDeductionGuideDecl *CXXDeductionGuideDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- return new (C, ID) CXXDeductionGuideDecl(C, nullptr, SourceLocation(), false,
- DeclarationNameInfo(), QualType(),
- nullptr, SourceLocation());
+ return new (C, ID) CXXDeductionGuideDecl(
+ C, nullptr, SourceLocation(), ExplicitSpecifier(), DeclarationNameInfo(),
+ QualType(), nullptr, SourceLocation());
}
void CXXMethodDecl::anchor() {}
@@ -1891,8 +1957,8 @@ static bool recursivelyOverrides(const CXXMethodDecl *DerivedMD,
}
CXXMethodDecl *
-CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
- bool MayBeBase) {
+CXXMethodDecl::getCorrespondingMethodDeclaredInClass(const CXXRecordDecl *RD,
+ bool MayBeBase) {
if (this->getParent()->getCanonicalDecl() == RD->getCanonicalDecl())
return this;
@@ -1918,6 +1984,15 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
return MD;
}
+ return nullptr;
+}
+
+CXXMethodDecl *
+CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
+ bool MayBeBase) {
+ if (auto *MD = getCorrespondingMethodDeclaredInClass(RD, MayBeBase))
+ return MD;
+
for (const auto &I : RD->bases()) {
const RecordType *RT = I.getType()->getAs<RecordType>();
if (!RT)
@@ -1931,22 +2006,22 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
return nullptr;
}
-CXXMethodDecl *
-CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass SC, bool isInline,
- bool isConstexpr, SourceLocation EndLocation) {
- return new (C, RD) CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo,
- T, TInfo, SC, isInline, isConstexpr,
- EndLocation);
+CXXMethodDecl *CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC, bool isInline,
+ ConstexprSpecKind ConstexprKind,
+ SourceLocation EndLocation) {
+ return new (C, RD)
+ CXXMethodDecl(CXXMethod, C, RD, StartLoc, NameInfo, T, TInfo, SC,
+ isInline, ConstexprKind, EndLocation);
}
CXXMethodDecl *CXXMethodDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- return new (C, ID) CXXMethodDecl(CXXMethod, C, nullptr, SourceLocation(),
- DeclarationNameInfo(), QualType(), nullptr,
- SC_None, false, false, SourceLocation());
+ return new (C, ID) CXXMethodDecl(
+ CXXMethod, C, nullptr, SourceLocation(), DeclarationNameInfo(),
+ QualType(), nullptr, SC_None, false, CSK_unspecified, SourceLocation());
}
CXXMethodDecl *CXXMethodDecl::getDevirtualizedMethod(const Expr *Base,
@@ -2081,8 +2156,13 @@ bool CXXMethodDecl::isUsualDeallocationFunction(
return false;
// In C++17 onwards, all potential usual deallocation functions are actual
- // usual deallocation functions.
- if (Context.getLangOpts().AlignedAllocation)
+ // usual deallocation functions. Honor this behavior when post-C++14
+ // deallocation functions are offered as extensions too.
+ // FIXME(EricWF): Destrying Delete should be a language option. How do we
+ // handle when destroying delete is used prior to C++17?
+ if (Context.getLangOpts().CPlusPlus17 ||
+ Context.getLangOpts().AlignedAllocation ||
+ isDestroyingOperatorDelete())
return true;
// This function is a usual deallocation function if there are no
@@ -2173,12 +2253,23 @@ CXXMethodDecl::overridden_methods() const {
return getASTContext().overridden_methods(this);
}
+static QualType getThisObjectType(ASTContext &C, const FunctionProtoType *FPT,
+ const CXXRecordDecl *Decl) {
+ QualType ClassTy = C.getTypeDeclType(Decl);
+ return C.getQualifiedType(ClassTy, FPT->getMethodQuals());
+}
+
QualType CXXMethodDecl::getThisType(const FunctionProtoType *FPT,
const CXXRecordDecl *Decl) {
ASTContext &C = Decl->getASTContext();
- QualType ClassTy = C.getTypeDeclType(Decl);
- ClassTy = C.getQualifiedType(ClassTy, FPT->getTypeQuals());
- return C.getPointerType(ClassTy);
+ QualType ObjectTy = ::getThisObjectType(C, FPT, Decl);
+ return C.getPointerType(ObjectTy);
+}
+
+QualType CXXMethodDecl::getThisObjectType(const FunctionProtoType *FPT,
+ const CXXRecordDecl *Decl) {
+ ASTContext &C = Decl->getASTContext();
+ return ::getThisObjectType(C, FPT, Decl);
}
QualType CXXMethodDecl::getThisType() const {
@@ -2193,6 +2284,14 @@ QualType CXXMethodDecl::getThisType() const {
getParent());
}
+QualType CXXMethodDecl::getThisObjectType() const {
+ // Ditto getThisType.
+ assert(isInstance() && "No 'this' for static methods!");
+
+ return CXXMethodDecl::getThisObjectType(getType()->getAs<FunctionProtoType>(),
+ getParent());
+}
+
bool CXXMethodDecl::hasInlineBody() const {
// If this function is a template instantiation, look at the template from
// which it was instantiated.
@@ -2297,47 +2396,55 @@ SourceRange CXXCtorInitializer::getSourceRange() const {
CXXConstructorDecl::CXXConstructorDecl(
ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
- bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared,
- bool isConstexpr, InheritedConstructor Inherited)
+ ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
+ ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited)
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
- SC_None, isInline, isConstexpr, SourceLocation()) {
+ SC_None, isInline, ConstexprKind, SourceLocation()) {
setNumCtorInitializers(0);
setInheritingConstructor(static_cast<bool>(Inherited));
setImplicit(isImplicitlyDeclared);
+ CXXConstructorDeclBits.HasTrailingExplicitSpecifier = ES.getExpr() ? 1 : 0;
if (Inherited)
*getTrailingObjects<InheritedConstructor>() = Inherited;
- setExplicitSpecified(isExplicitSpecified);
+ setExplicitSpecifier(ES);
}
void CXXConstructorDecl::anchor() {}
CXXConstructorDecl *CXXConstructorDecl::CreateDeserialized(ASTContext &C,
unsigned ID,
- bool Inherited) {
- unsigned Extra = additionalSizeToAlloc<InheritedConstructor>(Inherited);
- auto *Result = new (C, ID, Extra) CXXConstructorDecl(
- C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
- false, false, false, false, InheritedConstructor());
- Result->setInheritingConstructor(Inherited);
+ uint64_t AllocKind) {
+ bool hasTraillingExplicit = static_cast<bool>(AllocKind & TAKHasTailExplicit);
+ bool isInheritingConstructor =
+ static_cast<bool>(AllocKind & TAKInheritsConstructor);
+ unsigned Extra =
+ additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
+ isInheritingConstructor, hasTraillingExplicit);
+ auto *Result = new (C, ID, Extra)
+ CXXConstructorDecl(C, nullptr, SourceLocation(), DeclarationNameInfo(),
+ QualType(), nullptr, ExplicitSpecifier(), false, false,
+ CSK_unspecified, InheritedConstructor());
+ Result->setInheritingConstructor(isInheritingConstructor);
+ Result->CXXConstructorDeclBits.HasTrailingExplicitSpecifier =
+ hasTraillingExplicit;
+ Result->setExplicitSpecifier(ExplicitSpecifier());
return Result;
}
-CXXConstructorDecl *
-CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isExplicit, bool isInline,
- bool isImplicitlyDeclared, bool isConstexpr,
- InheritedConstructor Inherited) {
+CXXConstructorDecl *CXXConstructorDecl::Create(
+ ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ ExplicitSpecifier ES, bool isInline, bool isImplicitlyDeclared,
+ ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited) {
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
unsigned Extra =
- additionalSizeToAlloc<InheritedConstructor>(Inherited ? 1 : 0);
- return new (C, RD, Extra) CXXConstructorDecl(
- C, RD, StartLoc, NameInfo, T, TInfo, isExplicit, isInline,
- isImplicitlyDeclared, isConstexpr, Inherited);
+ additionalSizeToAlloc<InheritedConstructor, ExplicitSpecifier>(
+ Inherited ? 1 : 0, ES.getExpr() ? 1 : 0);
+ return new (C, RD, Extra)
+ CXXConstructorDecl(C, RD, StartLoc, NameInfo, T, TInfo, ES, isInline,
+ isImplicitlyDeclared, ConstexprKind, Inherited);
}
CXXConstructorDecl::init_const_iterator CXXConstructorDecl::init_begin() const {
@@ -2488,25 +2595,22 @@ void CXXConversionDecl::anchor() {}
CXXConversionDecl *
CXXConversionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- return new (C, ID) CXXConversionDecl(C, nullptr, SourceLocation(),
- DeclarationNameInfo(), QualType(),
- nullptr, false, false, false,
- SourceLocation());
+ return new (C, ID) CXXConversionDecl(
+ C, nullptr, SourceLocation(), DeclarationNameInfo(), QualType(), nullptr,
+ false, ExplicitSpecifier(), CSK_unspecified, SourceLocation());
}
-CXXConversionDecl *
-CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
- QualType T, TypeSourceInfo *TInfo,
- bool isInline, bool isExplicit,
- bool isConstexpr, SourceLocation EndLocation) {
+CXXConversionDecl *CXXConversionDecl::Create(
+ ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
+ bool isInline, ExplicitSpecifier ES, ConstexprSpecKind ConstexprKind,
+ SourceLocation EndLocation) {
assert(NameInfo.getName().getNameKind()
== DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function");
- return new (C, RD) CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo,
- isInline, isExplicit, isConstexpr,
- EndLocation);
+ return new (C, RD)
+ CXXConversionDecl(C, RD, StartLoc, NameInfo, T, TInfo, isInline, ES,
+ ConstexprKind, EndLocation);
}
bool CXXConversionDecl::isLambdaToBlockPointerConversion() const {
@@ -2857,6 +2961,12 @@ BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr);
}
+ValueDecl *BindingDecl::getDecomposedDecl() const {
+ ExternalASTSource *Source =
+ Decomp.isOffset() ? getASTContext().getExternalSource() : nullptr;
+ return cast_or_null<ValueDecl>(Decomp.get(Source));
+}
+
VarDecl *BindingDecl::getHoldingVar() const {
Expr *B = getBinding();
if (!B)
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp
index 08fbed361579..8ec1dea84df5 100644
--- a/lib/AST/DeclFriend.cpp
+++ b/lib/AST/DeclFriend.cpp
@@ -1,9 +1,8 @@
//===- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation ----===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DeclGroup.cpp b/lib/AST/DeclGroup.cpp
index f74ef9bbb839..27dbdaab6f30 100644
--- a/lib/AST/DeclGroup.cpp
+++ b/lib/AST/DeclGroup.cpp
@@ -1,9 +1,8 @@
//===- DeclGroup.cpp - Classes for representing groups of Decls -----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 1ed7fc71b025..bf748fbab8e9 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1,9 +1,8 @@
//===- DeclObjC.cpp - ObjC Declaration AST Node Implementation ------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -1642,7 +1641,7 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() {
if (!layout.empty()) {
// Order synthesized ivars by their size.
- std::stable_sort(layout.begin(), layout.end());
+ llvm::stable_sort(layout);
unsigned Ix = 0, EIx = layout.size();
if (!data().IvarList) {
data().IvarList = layout[0].Ivar; Ix++;
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
index b77a67cbf38d..af321280d417 100644
--- a/lib/AST/DeclOpenMP.cpp
+++ b/lib/AST/DeclOpenMP.cpp
@@ -1,9 +1,8 @@
//===--- DeclOpenMP.cpp - Declaration OpenMP AST Node Implementation ------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
@@ -54,6 +53,49 @@ void OMPThreadPrivateDecl::setVars(ArrayRef<Expr *> VL) {
}
//===----------------------------------------------------------------------===//
+// OMPAllocateDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPAllocateDecl::anchor() { }
+
+OMPAllocateDecl *OMPAllocateDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, ArrayRef<Expr *> VL,
+ ArrayRef<OMPClause *> CL) {
+ OMPAllocateDecl *D = new (
+ C, DC, additionalSizeToAlloc<Expr *, OMPClause *>(VL.size(), CL.size()))
+ OMPAllocateDecl(OMPAllocate, DC, L);
+ D->NumVars = VL.size();
+ D->setVars(VL);
+ D->NumClauses = CL.size();
+ D->setClauses(CL);
+ return D;
+}
+
+OMPAllocateDecl *OMPAllocateDecl::CreateDeserialized(ASTContext &C, unsigned ID,
+ unsigned NVars,
+ unsigned NClauses) {
+ OMPAllocateDecl *D =
+ new (C, ID, additionalSizeToAlloc<Expr *, OMPClause *>(NVars, NClauses))
+ OMPAllocateDecl(OMPAllocate, nullptr, SourceLocation());
+ D->NumVars = NVars;
+ D->NumClauses = NClauses;
+ return D;
+}
+
+void OMPAllocateDecl::setVars(ArrayRef<Expr *> VL) {
+ assert(VL.size() == NumVars &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::uninitialized_copy(VL.begin(), VL.end(), getTrailingObjects<Expr *>());
+}
+
+void OMPAllocateDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == NumClauses &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(),
+ getTrailingObjects<OMPClause *>());
+}
+
+//===----------------------------------------------------------------------===//
// OMPRequiresDecl Implementation.
//===----------------------------------------------------------------------===//
@@ -124,6 +166,66 @@ OMPDeclareReductionDecl::getPrevDeclInScope() const {
}
//===----------------------------------------------------------------------===//
+// OMPDeclareMapperDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPDeclareMapperDecl::anchor() {}
+
+OMPDeclareMapperDecl *
+OMPDeclareMapperDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, QualType T,
+ DeclarationName VarName,
+ OMPDeclareMapperDecl *PrevDeclInScope) {
+ return new (C, DC) OMPDeclareMapperDecl(OMPDeclareMapper, DC, L, Name, T,
+ VarName, PrevDeclInScope);
+}
+
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned N) {
+ auto *D = new (C, ID)
+ OMPDeclareMapperDecl(OMPDeclareMapper, /*DC=*/nullptr, SourceLocation(),
+ DeclarationName(), QualType(), DeclarationName(),
+ /*PrevDeclInScope=*/nullptr);
+ if (N) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(N);
+ D->Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, N);
+ }
+ return D;
+}
+
+/// Creates an array of clauses to this mapper declaration and intializes
+/// them. The space used to store clause pointers is dynamically allocated,
+/// because we do not know the number of clauses when creating
+/// OMPDeclareMapperDecl
+void OMPDeclareMapperDecl::CreateClauses(ASTContext &C,
+ ArrayRef<OMPClause *> CL) {
+ assert(Clauses.empty() && "Number of clauses should be 0 on initialization");
+ size_t NumClauses = CL.size();
+ if (NumClauses) {
+ auto **ClauseStorage = C.Allocate<OMPClause *>(NumClauses);
+ Clauses = llvm::makeMutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
+ setClauses(CL);
+ }
+}
+
+void OMPDeclareMapperDecl::setClauses(ArrayRef<OMPClause *> CL) {
+ assert(CL.size() == Clauses.size() &&
+ "Number of clauses is not the same as the preallocated buffer");
+ std::uninitialized_copy(CL.begin(), CL.end(), Clauses.data());
+}
+
+OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() {
+ return cast_or_null<OMPDeclareMapperDecl>(
+ PrevDeclInScope.get(getASTContext().getExternalSource()));
+}
+
+const OMPDeclareMapperDecl *OMPDeclareMapperDecl::getPrevDeclInScope() const {
+ return cast_or_null<OMPDeclareMapperDecl>(
+ PrevDeclInScope.get(getASTContext().getExternalSource()));
+}
+
+//===----------------------------------------------------------------------===//
// OMPCapturedExprDecl Implementation.
//===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 517851f9eeb1..f5c69944034a 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -1,9 +1,8 @@
//===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +15,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
@@ -100,11 +100,14 @@ namespace {
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
+ void VisitOMPAllocateDecl(OMPAllocateDecl *D);
void VisitOMPRequiresDecl(OMPRequiresDecl *D);
void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
+ void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
- void printTemplateParameters(const TemplateParameterList *Params);
+ void printTemplateParameters(const TemplateParameterList *Params,
+ bool OmitTemplateKW = false);
void printTemplateArguments(const TemplateArgumentList &Args,
const TemplateParameterList *Params = nullptr);