aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
committerDimitry Andric <dim@FreeBSD.org>2014-11-24 09:15:30 +0000
commit9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch)
tree47df2c12b57214af6c31e47404b005675b8b7ffc /lib
parentf73d5f23a889b93d89ddef61ac0995df40286bb8 (diff)
downloadsrc-9f4dbff6669c8037f3b036bcf580d14f1a4f12a5.tar.gz
src-9f4dbff6669c8037f3b036bcf580d14f1a4f12a5.zip
Vendor import of clang RELEASE_350/final tag r216957 (effectively, 3.5.0 release):vendor/clang/clang-release_350-r216957
Notes
Notes: svn path=/vendor/clang/dist/; revision=274958 svn path=/vendor/clang/clang-release_350-r216957/; revision=274959; tag=vendor/clang/clang-release_350-r216957
Diffstat (limited to 'lib')
-rw-r--r--lib/ARCMigrate/ARCMT.cpp87
-rw-r--r--lib/ARCMigrate/CMakeLists.txt30
-rw-r--r--lib/ARCMigrate/FileRemapper.cpp43
-rw-r--r--lib/ARCMigrate/Internals.h9
-rw-r--r--lib/ARCMigrate/ObjCMT.cpp710
-rw-r--r--lib/ARCMigrate/PlistReporter.cpp113
-rw-r--r--lib/ARCMigrate/TransAPIUses.cpp16
-rw-r--r--lib/ARCMigrate/TransAutoreleasePool.cpp8
-rw-r--r--lib/ARCMigrate/TransBlockObjCVariable.cpp7
-rw-r--r--lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp24
-rw-r--r--lib/ARCMigrate/TransGCAttrs.cpp12
-rw-r--r--lib/ARCMigrate/TransGCCalls.cpp10
-rw-r--r--lib/ARCMigrate/TransProperties.cpp31
-rw-r--r--lib/ARCMigrate/TransProtectedScope.cpp2
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp18
-rw-r--r--lib/ARCMigrate/TransUnbridgedCasts.cpp15
-rw-r--r--lib/ARCMigrate/TransUnusedInitDelegate.cpp2
-rw-r--r--lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp34
-rw-r--r--lib/ARCMigrate/TransformActions.cpp64
-rw-r--r--lib/ARCMigrate/Transforms.cpp23
-rw-r--r--lib/ARCMigrate/Transforms.h12
-rw-r--r--lib/AST/APValue.cpp93
-rw-r--r--lib/AST/ASTContext.cpp1554
-rw-r--r--lib/AST/ASTDiagnostic.cpp357
-rw-r--r--lib/AST/ASTDumper.cpp379
-rw-r--r--lib/AST/ASTImporter.cpp678
-rw-r--r--lib/AST/ASTTypeTraits.cpp16
-rw-r--r--lib/AST/AttrImpl.cpp2
-rw-r--r--lib/AST/CMakeLists.txt23
-rw-r--r--lib/AST/CXXABI.h1
-rw-r--r--lib/AST/CXXInheritance.cpp80
-rw-r--r--lib/AST/Comment.cpp46
-rw-r--r--lib/AST/CommentCommandTraits.cpp71
-rw-r--r--lib/AST/CommentLexer.cpp13
-rw-r--r--lib/AST/CommentParser.cpp6
-rw-r--r--lib/AST/CommentSema.cpp79
-rw-r--r--lib/AST/Decl.cpp762
-rw-r--r--lib/AST/DeclBase.cpp182
-rw-r--r--lib/AST/DeclCXX.cpp387
-rw-r--r--lib/AST/DeclFriend.cpp16
-rw-r--r--lib/AST/DeclObjC.cpp717
-rw-r--r--lib/AST/DeclOpenMP.cpp17
-rw-r--r--lib/AST/DeclPrinter.cpp153
-rw-r--r--lib/AST/DeclTemplate.cpp276
-rw-r--r--lib/AST/DeclarationName.cpp37
-rw-r--r--lib/AST/Expr.cpp274
-rw-r--r--lib/AST/ExprCXX.cpp140
-rw-r--r--lib/AST/ExprClassification.cpp24
-rw-r--r--lib/AST/ExprConstant.cpp472
-rw-r--r--lib/AST/ExternalASTSource.cpp52
-rw-r--r--lib/AST/InheritViz.cpp15
-rw-r--r--lib/AST/ItaniumCXXABI.cpp28
-rw-r--r--lib/AST/ItaniumMangle.cpp306
-rw-r--r--lib/AST/Mangle.cpp14
-rw-r--r--lib/AST/MangleNumberingContext.cpp10
-rw-r--r--lib/AST/MicrosoftCXXABI.cpp132
-rw-r--r--lib/AST/MicrosoftMangle.cpp1127
-rw-r--r--lib/AST/NSAPI.cpp6
-rw-r--r--lib/AST/NestedNameSpecifier.cpp34
-rw-r--r--lib/AST/ParentMap.cpp8
-rw-r--r--lib/AST/RawCommentList.cpp17
-rw-r--r--lib/AST/RecordLayout.cpp25
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp1554
-rw-r--r--lib/AST/Stmt.cpp588
-rw-r--r--lib/AST/StmtIterator.cpp8
-rw-r--r--lib/AST/StmtPrinter.cpp457
-rw-r--r--lib/AST/StmtProfile.cpp187
-rw-r--r--lib/AST/TemplateBase.cpp33
-rw-r--r--lib/AST/TemplateName.cpp4
-rw-r--r--lib/AST/Type.cpp192
-rw-r--r--lib/AST/TypeLoc.cpp4
-rw-r--r--lib/AST/TypePrinter.cpp93
-rw-r--r--lib/AST/VTTBuilder.cpp22
-rw-r--r--lib/AST/VTableBuilder.cpp855
-rw-r--r--lib/ASTMatchers/ASTMatchFinder.cpp90
-rw-r--r--lib/ASTMatchers/ASTMatchersInternal.cpp20
-rw-r--r--lib/ASTMatchers/CMakeLists.txt14
-rw-r--r--lib/ASTMatchers/Dynamic/CMakeLists.txt9
-rw-r--r--lib/ASTMatchers/Dynamic/Diagnostics.cpp4
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h591
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp264
-rw-r--r--lib/ASTMatchers/Dynamic/Registry.cpp211
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp40
-rw-r--r--lib/Analysis/AnalysisDeclContext.cpp86
-rw-r--r--lib/Analysis/BodyFarm.cpp164
-rw-r--r--lib/Analysis/BodyFarm.h7
-rw-r--r--lib/Analysis/CFG.cpp845
-rw-r--r--lib/Analysis/CFGReachabilityAnalysis.cpp3
-rw-r--r--lib/Analysis/CFGStmtMap.cpp6
-rw-r--r--lib/Analysis/CMakeLists.txt23
-rw-r--r--lib/Analysis/CallGraph.cpp26
-rw-r--r--lib/Analysis/Consumed.cpp712
-rw-r--r--lib/Analysis/FormatString.cpp6
-rw-r--r--lib/Analysis/FormatStringParsing.h4
-rw-r--r--lib/Analysis/LiveVariables.cpp67
-rw-r--r--lib/Analysis/PostOrderCFGView.cpp2
-rw-r--r--lib/Analysis/PrintfFormatString.cpp6
-rw-r--r--lib/Analysis/ProgramPoint.cpp7
-rw-r--r--lib/Analysis/PseudoConstantAnalysis.cpp7
-rw-r--r--lib/Analysis/ReachableCode.cpp515
-rw-r--r--lib/Analysis/ScanfFormatString.cpp34
-rw-r--r--lib/Analysis/ThreadSafety.cpp791
-rw-r--r--lib/Analysis/ThreadSafetyCommon.cpp794
-rw-r--r--lib/Analysis/ThreadSafetyLogical.cpp112
-rw-r--r--lib/Analysis/ThreadSafetyTIL.cpp153
-rw-r--r--lib/Analysis/UninitializedValues.cpp40
-rw-r--r--lib/Basic/Attributes.cpp17
-rw-r--r--lib/Basic/Builtins.cpp57
-rw-r--r--lib/Basic/CMakeLists.txt46
-rw-r--r--lib/Basic/Diagnostic.cpp212
-rw-r--r--lib/Basic/DiagnosticIDs.cpp268
-rw-r--r--lib/Basic/FileManager.cpp226
-rw-r--r--lib/Basic/FileSystemStatCache.cpp46
-rw-r--r--lib/Basic/IdentifierTable.cpp24
-rw-r--r--lib/Basic/Module.cpp41
-rw-r--r--lib/Basic/OpenMPKinds.cpp229
-rw-r--r--lib/Basic/SourceLocation.cpp7
-rw-r--r--lib/Basic/SourceManager.cpp135
-rw-r--r--lib/Basic/TargetInfo.cpp70
-rw-r--r--lib/Basic/Targets.cpp2624
-rw-r--r--lib/Basic/TokenKinds.cpp24
-rw-r--r--lib/Basic/Version.cpp16
-rw-r--r--lib/Basic/VirtualFileSystem.cpp1209
-rw-r--r--lib/Basic/Warnings.cpp (renamed from lib/Frontend/Warnings.cpp)87
-rw-r--r--lib/CMakeLists.txt4
-rw-r--r--lib/CodeGen/ABIInfo.h2
-rw-r--r--lib/CodeGen/BackendUtil.cpp192
-rw-r--r--lib/CodeGen/CGAtomic.cpp303
-rw-r--r--lib/CodeGen/CGBlocks.cpp275
-rw-r--r--lib/CodeGen/CGBlocks.h18
-rw-r--r--lib/CodeGen/CGBuilder.h31
-rw-r--r--lib/CodeGen/CGBuiltin.cpp6219
-rw-r--r--lib/CodeGen/CGCUDANV.cpp4
-rw-r--r--lib/CodeGen/CGCUDARuntime.cpp7
-rw-r--r--lib/CodeGen/CGCXX.cpp80
-rw-r--r--lib/CodeGen/CGCXXABI.cpp67
-rw-r--r--lib/CodeGen/CGCXXABI.h153
-rw-r--r--lib/CodeGen/CGCall.cpp832
-rw-r--r--lib/CodeGen/CGCall.h30
-rw-r--r--lib/CodeGen/CGClass.cpp289
-rw-r--r--lib/CodeGen/CGCleanup.cpp36
-rw-r--r--lib/CodeGen/CGCleanup.h23
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp801
-rw-r--r--lib/CodeGen/CGDebugInfo.h94
-rw-r--r--lib/CodeGen/CGDecl.cpp199
-rw-r--r--lib/CodeGen/CGDeclCXX.cpp208
-rw-r--r--lib/CodeGen/CGException.cpp226
-rw-r--r--lib/CodeGen/CGExpr.cpp542
-rw-r--r--lib/CodeGen/CGExprAgg.cpp86
-rw-r--r--lib/CodeGen/CGExprCXX.cpp739
-rw-r--r--lib/CodeGen/CGExprComplex.cpp17
-rw-r--r--lib/CodeGen/CGExprConstant.cpp111
-rw-r--r--lib/CodeGen/CGExprScalar.cpp217
-rw-r--r--lib/CodeGen/CGLoopInfo.cpp112
-rw-r--r--lib/CodeGen/CGLoopInfo.h136
-rw-r--r--lib/CodeGen/CGObjC.cpp196
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp546
-rw-r--r--lib/CodeGen/CGObjCMac.cpp1322
-rw-r--r--lib/CodeGen/CGObjCRuntime.cpp16
-rw-r--r--lib/CodeGen/CGObjCRuntime.h9
-rw-r--r--lib/CodeGen/CGOpenCLRuntime.cpp21
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp182
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h177
-rw-r--r--lib/CodeGen/CGRTTI.cpp977
-rw-r--r--lib/CodeGen/CGRecordLayout.h6
-rw-r--r--lib/CodeGen/CGRecordLayoutBuilder.cpp1428
-rw-r--r--lib/CodeGen/CGStmt.cpp524
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp130
-rw-r--r--lib/CodeGen/CGVTT.cpp5
-rw-r--r--lib/CodeGen/CGVTables.cpp175
-rw-r--r--lib/CodeGen/CGVTables.h24
-rw-r--r--lib/CodeGen/CGValue.h27
-rw-r--r--lib/CodeGen/CMakeLists.txt55
-rw-r--r--lib/CodeGen/CodeGenABITypes.cpp20
-rw-r--r--lib/CodeGen/CodeGenAction.cpp447
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp374
-rw-r--r--lib/CodeGen/CodeGenFunction.h413
-rw-r--r--lib/CodeGen/CodeGenModule.cpp1561
-rw-r--r--lib/CodeGen/CodeGenModule.h818
-rw-r--r--lib/CodeGen/CodeGenPGO.cpp1011
-rw-r--r--lib/CodeGen/CodeGenPGO.h236
-rw-r--r--lib/CodeGen/CodeGenTBAA.cpp16
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp59
-rw-r--r--lib/CodeGen/CodeGenTypes.h19
-rw-r--r--lib/CodeGen/EHScopeStack.h20
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp1710
-rw-r--r--lib/CodeGen/MicrosoftCXXABI.cpp1872
-rw-r--r--lib/CodeGen/MicrosoftVBTables.cpp233
-rw-r--r--lib/CodeGen/MicrosoftVBTables.h129
-rw-r--r--lib/CodeGen/ModuleBuilder.cpp106
-rw-r--r--lib/CodeGen/SanitizerBlacklist.cpp52
-rw-r--r--lib/CodeGen/SanitizerBlacklist.h46
-rw-r--r--lib/CodeGen/TargetInfo.cpp3005
-rw-r--r--lib/CodeGen/TargetInfo.h360
-rw-r--r--lib/Driver/Action.cpp30
-rw-r--r--lib/Driver/CC1AsOptions.cpp44
-rw-r--r--lib/Driver/CMakeLists.txt19
-rw-r--r--lib/Driver/Compilation.cpp21
-rw-r--r--lib/Driver/Driver.cpp324
-rw-r--r--lib/Driver/Job.cpp16
-rw-r--r--lib/Driver/Multilib.cpp334
-rw-r--r--lib/Driver/SanitizerArgs.cpp127
-rw-r--r--lib/Driver/ToolChain.cpp199
-rw-r--r--lib/Driver/ToolChains.cpp1573
-rw-r--r--lib/Driver/ToolChains.h615
-rw-r--r--lib/Driver/Tools.cpp2884
-rw-r--r--lib/Driver/Tools.h524
-rw-r--r--lib/Driver/Types.cpp2
-rw-r--r--lib/Driver/WindowsToolChain.cpp91
-rw-r--r--lib/Edit/CMakeLists.txt18
-rw-r--r--lib/Edit/Commit.cpp12
-rw-r--r--lib/Edit/EditedSource.cpp8
-rw-r--r--lib/Edit/RewriteObjCFoundationAPI.cpp9
-rw-r--r--lib/Format/BreakableToken.cpp60
-rw-r--r--lib/Format/BreakableToken.h63
-rw-r--r--lib/Format/CMakeLists.txt18
-rw-r--r--lib/Format/ContinuationIndenter.cpp759
-rw-r--r--lib/Format/ContinuationIndenter.h70
-rw-r--r--lib/Format/Encoding.h8
-rw-r--r--lib/Format/Format.cpp1192
-rw-r--r--lib/Format/FormatToken.cpp83
-rw-r--r--lib/Format/FormatToken.h99
-rw-r--r--lib/Format/TokenAnnotator.cpp804
-rw-r--r--lib/Format/TokenAnnotator.h19
-rw-r--r--lib/Format/UnwrappedLineParser.cpp483
-rw-r--r--lib/Format/UnwrappedLineParser.h25
-rw-r--r--lib/Format/WhitespaceManager.cpp150
-rw-r--r--lib/Format/WhitespaceManager.h28
-rw-r--r--lib/Frontend/ASTConsumers.cpp60
-rw-r--r--lib/Frontend/ASTMerge.cpp8
-rw-r--r--lib/Frontend/ASTUnit.cpp988
-rw-r--r--lib/Frontend/CMakeLists.txt27
-rw-r--r--lib/Frontend/CacheTokens.cpp96
-rw-r--r--lib/Frontend/ChainedIncludesSource.cpp134
-rw-r--r--lib/Frontend/CompilerInstance.cpp695
-rw-r--r--lib/Frontend/CompilerInvocation.cpp365
-rw-r--r--lib/Frontend/CreateInvocationFromCommandLine.cpp18
-rw-r--r--lib/Frontend/DependencyFile.cpp230
-rw-r--r--lib/Frontend/DependencyGraph.cpp20
-rw-r--r--lib/Frontend/DiagnosticRenderer.cpp24
-rw-r--r--lib/Frontend/FrontendAction.cpp180
-rw-r--r--lib/Frontend/FrontendActions.cpp227
-rw-r--r--lib/Frontend/HeaderIncludeGen.cpp12
-rw-r--r--lib/Frontend/InitHeaderSearch.cpp100
-rw-r--r--lib/Frontend/InitPreprocessor.cpp335
-rw-r--r--lib/Frontend/LangStandards.cpp2
-rw-r--r--lib/Frontend/LogDiagnosticPrinter.cpp90
-rw-r--r--lib/Frontend/Makefile2
-rw-r--r--lib/Frontend/ModuleDependencyCollector.cpp116
-rw-r--r--lib/Frontend/MultiplexConsumer.cpp90
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp147
-rw-r--r--lib/Frontend/Rewrite/CMakeLists.txt22
-rw-r--r--lib/Frontend/Rewrite/FixItRewriter.cpp (renamed from lib/Rewrite/Frontend/FixItRewriter.cpp)10
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp (renamed from lib/Rewrite/Frontend/FrontendActions.cpp)30
-rw-r--r--lib/Frontend/Rewrite/HTMLPrint.cpp (renamed from lib/Rewrite/Frontend/HTMLPrint.cpp)4
-rw-r--r--lib/Frontend/Rewrite/InclusionRewriter.cpp (renamed from lib/Rewrite/Frontend/InclusionRewriter.cpp)85
-rw-r--r--lib/Frontend/Rewrite/Makefile (renamed from lib/Rewrite/Frontend/Makefile)4
-rw-r--r--lib/Frontend/Rewrite/RewriteMacros.cpp (renamed from lib/Rewrite/Frontend/RewriteMacros.cpp)2
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp (renamed from lib/Rewrite/Frontend/RewriteModernObjC.cpp)683
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp (renamed from lib/Rewrite/Frontend/RewriteObjC.cpp)509
-rw-r--r--lib/Frontend/Rewrite/RewriteTest.cpp (renamed from lib/Rewrite/Frontend/RewriteTest.cpp)0
-rw-r--r--lib/Frontend/SerializedDiagnosticPrinter.cpp98
-rw-r--r--lib/Frontend/TextDiagnostic.cpp62
-rw-r--r--lib/Frontend/TextDiagnosticBuffer.cpp38
-rw-r--r--lib/Frontend/TextDiagnosticPrinter.cpp11
-rw-r--r--lib/Frontend/VerifyDiagnosticConsumer.cpp162
-rw-r--r--lib/FrontendTool/CMakeLists.txt33
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp54
-rw-r--r--lib/FrontendTool/Makefile5
-rw-r--r--lib/Headers/CMakeLists.txt48
-rw-r--r--lib/Headers/Intrin.h320
-rw-r--r--lib/Headers/Makefile8
-rw-r--r--lib/Headers/altivec.h479
-rw-r--r--lib/Headers/arm_acle.h191
-rw-r--r--lib/Headers/avx2intrin.h34
-rw-r--r--lib/Headers/avxintrin.h25
-rw-r--r--lib/Headers/bmiintrin.h35
-rw-r--r--lib/Headers/cpuid.h1
-rw-r--r--lib/Headers/float.h2
-rw-r--r--lib/Headers/ia32intrin.h101
-rw-r--r--lib/Headers/immintrin.h2
-rw-r--r--lib/Headers/limits.h5
-rw-r--r--lib/Headers/module.modulemap (renamed from lib/Headers/module.map)0
-rw-r--r--lib/Headers/smmintrin.h20
-rw-r--r--lib/Headers/stdarg.h4
-rw-r--r--lib/Headers/stddef.h52
-rw-r--r--lib/Headers/stdint.h35
-rw-r--r--lib/Headers/x86intrin.h4
-rw-r--r--lib/Headers/xmmintrin.h10
-rw-r--r--lib/Index/CMakeLists.txt16
-rw-r--r--lib/Index/CommentToXML.cpp64
-rw-r--r--lib/Index/SimpleFormatContext.h9
-rw-r--r--lib/Index/USRGeneration.cpp142
-rw-r--r--lib/Lex/CMakeLists.txt9
-rw-r--r--lib/Lex/HeaderMap.cpp41
-rw-r--r--lib/Lex/HeaderSearch.cpp621
-rw-r--r--lib/Lex/Lexer.cpp223
-rw-r--r--lib/Lex/LiteralSupport.cpp148
-rw-r--r--lib/Lex/MacroArgs.cpp8
-rw-r--r--lib/Lex/MacroInfo.cpp86
-rw-r--r--lib/Lex/ModuleMap.cpp605
-rw-r--r--lib/Lex/PPCaching.cpp22
-rw-r--r--lib/Lex/PPConditionalDirectiveRecord.cpp4
-rw-r--r--lib/Lex/PPDirectives.cpp441
-rw-r--r--lib/Lex/PPExpressions.cpp28
-rw-r--r--lib/Lex/PPLexerChange.cpp128
-rw-r--r--lib/Lex/PPMacroExpansion.cpp210
-rw-r--r--lib/Lex/PTHLexer.cpp198
-rw-r--r--lib/Lex/Pragma.cpp184
-rw-r--r--lib/Lex/PreprocessingRecord.cpp10
-rw-r--r--lib/Lex/Preprocessor.cpp136
-rw-r--r--lib/Lex/ScratchBuffer.cpp5
-rw-r--r--lib/Lex/TokenLexer.cpp93
-rw-r--r--lib/Lex/UnicodeCharSets.h2
-rwxr-xr-xlib/Makefile6
-rw-r--r--lib/Parse/CMakeLists.txt26
-rw-r--r--lib/Parse/ParseAST.cpp11
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp142
-rw-r--r--lib/Parse/ParseDecl.cpp1611
-rw-r--r--lib/Parse/ParseDeclCXX.cpp845
-rw-r--r--lib/Parse/ParseExpr.cpp386
-rw-r--r--lib/Parse/ParseExprCXX.cpp464
-rw-r--r--lib/Parse/ParseInit.cpp84
-rw-r--r--lib/Parse/ParseObjc.cpp368
-rw-r--r--lib/Parse/ParseOpenMP.cpp513
-rw-r--r--lib/Parse/ParsePragma.cpp1062
-rw-r--r--lib/Parse/ParsePragma.h139
-rw-r--r--lib/Parse/ParseStmt.cpp1150
-rw-r--r--lib/Parse/ParseStmtAsm.cpp761
-rw-r--r--lib/Parse/ParseTemplate.cpp257
-rw-r--r--lib/Parse/ParseTentative.cpp400
-rw-r--r--lib/Parse/Parser.cpp439
-rw-r--r--lib/Parse/RAIIObjectsForParser.h16
-rw-r--r--lib/Rewrite/CMakeLists.txt18
-rw-r--r--lib/Rewrite/Core/CMakeLists.txt24
-rw-r--r--lib/Rewrite/Core/Makefile18
-rw-r--r--lib/Rewrite/DeltaTree.cpp (renamed from lib/Rewrite/Core/DeltaTree.cpp)4
-rw-r--r--lib/Rewrite/Frontend/CMakeLists.txt29
-rw-r--r--lib/Rewrite/HTMLRewrite.cpp (renamed from lib/Rewrite/Core/HTMLRewrite.cpp)4
-rw-r--r--lib/Rewrite/Makefile10
-rw-r--r--lib/Rewrite/RewriteRope.cpp (renamed from lib/Rewrite/Core/RewriteRope.cpp)35
-rw-r--r--lib/Rewrite/Rewriter.cpp (renamed from lib/Rewrite/Core/Rewriter.cpp)28
-rw-r--r--lib/Rewrite/TokenRewriter.cpp (renamed from lib/Rewrite/Core/TokenRewriter.cpp)0
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp604
-rw-r--r--lib/Sema/AttributeList.cpp72
-rw-r--r--lib/Sema/CMakeLists.txt28
-rw-r--r--lib/Sema/CodeCompleteConsumer.cpp11
-rw-r--r--lib/Sema/DeclSpec.cpp178
-rw-r--r--lib/Sema/DelayedDiagnostic.cpp24
-rw-r--r--lib/Sema/IdentifierResolver.cpp23
-rw-r--r--lib/Sema/JumpDiagnostics.cpp169
-rw-r--r--lib/Sema/MultiplexExternalSemaSource.cpp11
-rw-r--r--lib/Sema/Scope.cpp161
-rw-r--r--lib/Sema/ScopeInfo.cpp32
-rw-r--r--lib/Sema/Sema.cpp236
-rw-r--r--lib/Sema/SemaAccess.cpp109
-rw-r--r--lib/Sema/SemaAttr.cpp224
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp169
-rw-r--r--lib/Sema/SemaCast.cpp124
-rw-r--r--lib/Sema/SemaChecking.cpp1959
-rw-r--r--lib/Sema/SemaCodeComplete.cpp592
-rw-r--r--lib/Sema/SemaDecl.cpp2814
-rw-r--r--lib/Sema/SemaDeclAttr.cpp3054
-rw-r--r--lib/Sema/SemaDeclCXX.cpp2327
-rw-r--r--lib/Sema/SemaDeclObjC.cpp883
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp134
-rw-r--r--lib/Sema/SemaExpr.cpp2250
-rw-r--r--lib/Sema/SemaExprCXX.cpp1162
-rw-r--r--lib/Sema/SemaExprMember.cpp470
-rw-r--r--lib/Sema/SemaExprObjC.cpp990
-rw-r--r--lib/Sema/SemaInit.cpp861
-rw-r--r--lib/Sema/SemaLambda.cpp460
-rw-r--r--lib/Sema/SemaLookup.cpp1352
-rw-r--r--lib/Sema/SemaObjCProperty.cpp581
-rw-r--r--lib/Sema/SemaOpenMP.cpp3628
-rw-r--r--lib/Sema/SemaOverload.cpp1092
-rw-r--r--lib/Sema/SemaPseudoObject.cpp249
-rw-r--r--lib/Sema/SemaStmt.cpp734
-rw-r--r--lib/Sema/SemaStmtAsm.cpp31
-rw-r--r--lib/Sema/SemaStmtAttr.cpp165
-rw-r--r--lib/Sema/SemaTemplate.cpp920
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp642
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp491
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp689
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp38
-rw-r--r--lib/Sema/SemaType.cpp942
-rw-r--r--lib/Sema/TargetAttributesSema.cpp353
-rw-r--r--lib/Sema/TargetAttributesSema.h27
-rw-r--r--lib/Sema/TreeTransform.h1737
-rw-r--r--lib/Sema/TypeLocBuilder.cpp2
-rw-r--r--lib/Sema/TypeLocBuilder.h2
-rw-r--r--lib/Serialization/ASTCommon.cpp12
-rw-r--r--lib/Serialization/ASTCommon.h7
-rw-r--r--lib/Serialization/ASTReader.cpp2025
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp851
-rw-r--r--lib/Serialization/ASTReaderInternals.h32
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp442
-rw-r--r--lib/Serialization/ASTWriter.cpp1104
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp159
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp300
-rw-r--r--lib/Serialization/CMakeLists.txt31
-rw-r--r--lib/Serialization/GeneratePCH.cpp2
-rw-r--r--lib/Serialization/GlobalModuleIndex.cpp116
-rw-r--r--lib/Serialization/Module.cpp30
-rw-r--r--lib/Serialization/ModuleManager.cpp96
-rw-r--r--lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp243
-rw-r--r--lib/StaticAnalyzer/Checkers/BoolAssignmentChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/CMakeLists.txt22
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringChecker.cpp167
-rw-r--r--lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp13
-rw-r--r--lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp219
-rw-r--r--lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp93
-rw-r--r--lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCDealloc.cpp45
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckObjCInstMethSignature.cpp41
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp108
-rw-r--r--lib/StaticAnalyzer/Checkers/CheckSizeofPointer.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/Checkers.td20
-rw-r--r--lib/StaticAnalyzer/Checkers/ChrootChecker.cpp12
-rw-r--r--lib/StaticAnalyzer/Checkers/DeadStoresChecker.cpp42
-rw-r--r--lib/StaticAnalyzer/Checkers/DebugCheckers.cpp5
-rw-r--r--lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/DirectIvarAssignment.cpp44
-rw-r--r--lib/StaticAnalyzer/Checkers/DivZeroChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/FixedAddressChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp25
-rw-r--r--lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp737
-rw-r--r--lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp404
-rw-r--r--lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp97
-rw-r--r--lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp56
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/MacOSXAPIChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp606
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocOverflowSecurityChecker.cpp20
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/NSAutoreleasePoolChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp63
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp37
-rw-r--r--lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp28
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCAtSyncChecker.cpp15
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp17
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCContainersChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCMissingSuperCallChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCSelfInitChecker.cpp42
-rw-r--r--lib/StaticAnalyzer/Checkers/ObjCUnusedIVarsChecker.cpp43
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerArithChecker.cpp11
-rw-r--r--lib/StaticAnalyzer/Checkers/PointerSubChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp223
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp434
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnPointerRangeChecker.cpp10
-rw-r--r--lib/StaticAnalyzer/Checkers/ReturnUndefChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/SelectorExtras.h68
-rw-r--r--lib/StaticAnalyzer/Checkers/SimpleStreamChecker.cpp18
-rw-r--r--lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp22
-rw-r--r--lib/StaticAnalyzer/Checkers/StreamChecker.cpp47
-rw-r--r--lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/TestAfterDivZeroChecker.cpp264
-rw-r--r--lib/StaticAnalyzer/Checkers/TraversalChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefBranchChecker.cpp8
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefCapturedBlockVarChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedArraySubscriptChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp6
-rw-r--r--lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp33
-rw-r--r--lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp23
-rw-r--r--lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp9
-rw-r--r--lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp25
-rw-r--r--lib/StaticAnalyzer/Core/AnalyzerOptions.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/BasicValueFactory.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/BlockCounter.cpp3
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp175
-rw-r--r--lib/StaticAnalyzer/Core/BugReporterVisitors.cpp193
-rw-r--r--lib/StaticAnalyzer/Core/CMakeLists.txt18
-rw-r--r--lib/StaticAnalyzer/Core/CallEvent.cpp122
-rw-r--r--lib/StaticAnalyzer/Core/Checker.cpp19
-rw-r--r--lib/StaticAnalyzer/Core/CheckerManager.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/CheckerRegistry.cpp7
-rw-r--r--lib/StaticAnalyzer/Core/CoreEngine.cpp59
-rw-r--r--lib/StaticAnalyzer/Core/Environment.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/ExplodedGraph.cpp28
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp311
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineC.cpp89
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCXX.cpp168
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp66
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineObjC.cpp6
-rw-r--r--lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp105
-rw-r--r--lib/StaticAnalyzer/Core/MemRegion.cpp64
-rw-r--r--lib/StaticAnalyzer/Core/PathDiagnostic.cpp94
-rw-r--r--lib/StaticAnalyzer/Core/PlistDiagnostics.cpp140
-rw-r--r--lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h2
-rw-r--r--lib/StaticAnalyzer/Core/ProgramState.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/RangeConstraintManager.cpp54
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp67
-rw-r--r--lib/StaticAnalyzer/Core/SValBuilder.cpp4
-rw-r--r--lib/StaticAnalyzer/Core/SVals.cpp12
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp2
-rw-r--r--lib/StaticAnalyzer/Core/SimpleConstraintManager.h4
-rw-r--r--lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp47
-rw-r--r--lib/StaticAnalyzer/Core/Store.cpp10
-rw-r--r--lib/StaticAnalyzer/Core/SymbolManager.cpp12
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp164
-rw-r--r--lib/StaticAnalyzer/Frontend/AnalysisConsumer.h43
-rw-r--r--lib/StaticAnalyzer/Frontend/CMakeLists.txt28
-rw-r--r--lib/StaticAnalyzer/Frontend/CheckerRegistration.cpp12
-rw-r--r--lib/StaticAnalyzer/Frontend/FrontendActions.cpp2
-rw-r--r--lib/Tooling/CMakeLists.txt21
-rw-r--r--lib/Tooling/CommonOptionsParser.cpp20
-rw-r--r--lib/Tooling/CompilationDatabase.cpp56
-rw-r--r--lib/Tooling/FileMatchTrie.cpp2
-rw-r--r--lib/Tooling/JSONCompilationDatabase.cpp59
-rw-r--r--lib/Tooling/Refactoring.cpp20
-rw-r--r--lib/Tooling/Tooling.cpp132
517 files changed, 80973 insertions, 50663 deletions
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index 3e429beded5d..8a13b2ee4f1d 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -103,8 +103,8 @@ public:
: Diags(diags), DiagClient(client), CapturedDiags(capturedDiags),
HasBegunSourceFile(false) { }
- virtual void BeginSourceFile(const LangOptions &Opts,
- const Preprocessor *PP) {
+ void BeginSourceFile(const LangOptions &Opts,
+ const Preprocessor *PP) override {
// Pass BeginSourceFile message onto DiagClient on first call.
// The corresponding EndSourceFile call will be made from an
// explicit call to FinishCapture.
@@ -128,8 +128,8 @@ public:
assert(!HasBegunSourceFile && "FinishCapture not called!");
}
- virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
- const Diagnostic &Info) {
+ void HandleDiagnostic(DiagnosticsEngine::Level level,
+ const Diagnostic &Info) override {
if (DiagnosticIDs::isARCDiagnostic(Info.getID()) ||
level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
if (Info.getLocation().isValid())
@@ -167,7 +167,7 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
static CompilerInvocation *
createInvocationForMigration(CompilerInvocation &origCI) {
- OwningPtr<CompilerInvocation> CInvok;
+ std::unique_ptr<CompilerInvocation> CInvok;
CInvok.reset(new CompilerInvocation(origCI));
PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
if (!PPOpts.ImplicitPCHInclude.empty()) {
@@ -204,11 +204,11 @@ createInvocationForMigration(CompilerInvocation &origCI) {
WarnOpts.push_back(*I);
}
WarnOpts.push_back("error=arc-unsafe-retained-assign");
- CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts);
+ CInvok->getDiagnosticOpts().Warnings = std::move(WarnOpts);
CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI);
- return CInvok.take();
+ return CInvok.release();
}
static void emitPremigrationErrors(const CapturedDiagList &arcDiags,
@@ -246,7 +246,7 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
NoFinalizeRemoval);
assert(!transforms.empty());
- OwningPtr<CompilerInvocation> CInvok;
+ std::unique_ptr<CompilerInvocation> CInvok;
CInvok.reset(createInvocationForMigration(origCI));
CInvok->getFrontendOpts().Inputs.clear();
CInvok->getFrontendOpts().Inputs.push_back(Input);
@@ -263,8 +263,8 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
- OwningPtr<ASTUnit> Unit(
- ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags));
+ std::unique_ptr<ASTUnit> Unit(
+ ASTUnit::LoadFromCompilerInvocationAction(CInvok.release(), Diags));
if (!Unit) {
errRec.FinishCapture();
return true;
@@ -310,8 +310,10 @@ bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
TransformActions testAct(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
MigrationPass pass(Ctx, OrigGCMode, Unit->getSema(), testAct, capturedDiags,
ARCMTMacroLocs);
- pass.setNSAllocReallocError(NoNSAllocReallocError);
pass.setNoFinalizeRemoval(NoFinalizeRemoval);
+ if (!NoNSAllocReallocError)
+ Diags->setSeverity(diag::warn_arcmt_nsalloc_realloc, diag::Severity::Error,
+ SourceLocation());
for (unsigned i=0, e = transforms.size(); i != e; ++i)
transforms[i](pass);
@@ -416,44 +418,6 @@ bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > &
return false;
}
-bool arcmt::getFileRemappingsFromFileList(
- std::vector<std::pair<std::string,std::string> > &remap,
- ArrayRef<StringRef> remapFiles,
- DiagnosticConsumer *DiagClient) {
- bool hasErrorOccurred = false;
- llvm::StringMap<bool> Uniquer;
-
- IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
- IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
- new DiagnosticsEngine(DiagID, new DiagnosticOptions,
- DiagClient, /*ShouldOwnClient=*/false));
-
- for (ArrayRef<StringRef>::iterator
- I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
- StringRef file = *I;
-
- FileRemapper remapper;
- bool err = remapper.initFromFile(file, *Diags,
- /*ignoreIfFilesChanged=*/true);
- hasErrorOccurred = hasErrorOccurred || err;
- if (err)
- continue;
-
- PreprocessorOptions PPOpts;
- remapper.applyMappings(PPOpts);
- for (PreprocessorOptions::remapped_file_iterator
- RI = PPOpts.remapped_file_begin(), RE = PPOpts.remapped_file_end();
- RI != RE; ++RI) {
- bool &inserted = Uniquer[RI->first];
- if (inserted)
- continue;
- inserted = true;
- remap.push_back(*RI);
- }
- }
-
- return hasErrorOccurred;
-}
//===----------------------------------------------------------------------===//
// CollectTransformActions.
@@ -468,8 +432,8 @@ public:
ARCMTMacroTrackerPPCallbacks(std::vector<SourceLocation> &ARCMTMacroLocs)
: ARCMTMacroLocs(ARCMTMacroLocs) { }
- virtual void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
- SourceRange Range, const MacroArgs *Args) {
+ void MacroExpands(const Token &MacroNameTok, const MacroDirective *MD,
+ SourceRange Range, const MacroArgs *Args) override {
if (MacroNameTok.getIdentifierInfo()->getName() == getARCMTMacroName())
ARCMTMacroLocs.push_back(MacroNameTok.getLocation());
}
@@ -482,8 +446,8 @@ public:
ARCMTMacroTrackerAction(std::vector<SourceLocation> &ARCMTMacroLocs)
: ARCMTMacroLocs(ARCMTMacroLocs) { }
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile) {
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override {
CI.getPreprocessor().addPPCallbacks(
new ARCMTMacroTrackerPPCallbacks(ARCMTMacroLocs));
return new ASTConsumer();
@@ -506,14 +470,14 @@ public:
Listener->finish();
}
- virtual void insert(SourceLocation loc, StringRef text) {
+ void insert(SourceLocation loc, StringRef text) override {
bool err = rewriter.InsertText(loc, text, /*InsertAfter=*/true,
/*indentNewLines=*/true);
if (!err && Listener)
Listener->insert(loc, text);
}
- virtual void remove(CharSourceRange range) {
+ void remove(CharSourceRange range) override {
Rewriter::RewriteOptions removeOpts;
removeOpts.IncludeInsertsAtBeginOfRange = false;
removeOpts.IncludeInsertsAtEndOfRange = false;
@@ -524,8 +488,8 @@ public:
Listener->remove(range);
}
- virtual void increaseIndentation(CharSourceRange range,
- SourceLocation parentIndent) {
+ void increaseIndentation(CharSourceRange range,
+ SourceLocation parentIndent) override {
rewriter.IncreaseIndentation(range, parentIndent);
}
};
@@ -550,7 +514,7 @@ MigrationProcess::MigrationProcess(const CompilerInvocation &CI,
bool MigrationProcess::applyTransform(TransformFn trans,
RewriteListener *listener) {
- OwningPtr<CompilerInvocation> CInvok;
+ std::unique_ptr<CompilerInvocation> CInvok;
CInvok.reset(createInvocationForMigration(OrigCI));
CInvok->getDiagnosticOpts().IgnoreWarnings = true;
@@ -569,12 +533,11 @@ bool MigrationProcess::applyTransform(TransformFn trans,
CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
- OwningPtr<ARCMTMacroTrackerAction> ASTAction;
+ std::unique_ptr<ARCMTMacroTrackerAction> ASTAction;
ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs));
- OwningPtr<ASTUnit> Unit(
- ASTUnit::LoadFromCompilerInvocationAction(CInvok.take(), Diags,
- ASTAction.get()));
+ std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
+ CInvok.release(), Diags, ASTAction.get()));
if (!Unit) {
errRec.FinishCapture();
return true;
diff --git a/lib/ARCMigrate/CMakeLists.txt b/lib/ARCMigrate/CMakeLists.txt
index c55261277dd1..b716a20fe63f 100644
--- a/lib/ARCMigrate/CMakeLists.txt
+++ b/lib/ARCMigrate/CMakeLists.txt
@@ -1,3 +1,7 @@
+set(LLVM_LINK_COMPONENTS
+ Support
+ )
+
add_clang_library(clangARCMigrate
ARCMT.cpp
ARCMTActions.cpp
@@ -19,26 +23,16 @@ add_clang_library(clangARCMigrate
TransZeroOutPropsInDealloc.cpp
TransformActions.cpp
Transforms.cpp
- )
-add_dependencies(clangARCMigrate
- ClangAttrClasses
- ClangAttrList
- ClangAttrParsedAttrList
- ClangCommentNodes
- ClangDeclNodes
- ClangDiagnosticCommon
- ClangDiagnosticGroups
- ClangDiagnosticSema
- ClangStmtNodes
- )
-
-target_link_libraries(clangARCMigrate
- clangBasic
+ LINK_LIBS
clangAST
- clangParse
+ clangAnalysis
+ clangBasic
+ clangEdit
clangFrontend
- clangRewriteCore
- clangRewriteFrontend
+ clangLex
+ clangRewrite
+ clangSema
+ clangSerialization
clangStaticAnalyzerCheckers
)
diff --git a/lib/ARCMigrate/FileRemapper.cpp b/lib/ARCMigrate/FileRemapper.cpp
index a14226e43fe0..40e606090064 100644
--- a/lib/ARCMigrate/FileRemapper.cpp
+++ b/lib/ARCMigrate/FileRemapper.cpp
@@ -36,8 +36,7 @@ void FileRemapper::clear(StringRef outputDir) {
assert(ToFromMappings.empty());
if (!outputDir.empty()) {
std::string infoFile = getRemapInfoFile(outputDir);
- bool existed;
- llvm::sys::fs::remove(infoFile, existed);
+ llvm::sys::fs::remove(infoFile);
}
}
@@ -65,13 +64,14 @@ bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
return false;
std::vector<std::pair<const FileEntry *, const FileEntry *> > pairs;
-
- OwningPtr<llvm::MemoryBuffer> fileBuf;
- if (llvm::MemoryBuffer::getFile(infoFile.c_str(), fileBuf))
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileBuf =
+ llvm::MemoryBuffer::getFile(infoFile.c_str());
+ if (!fileBuf)
return report("Error opening file: " + infoFile, Diag);
SmallVector<StringRef, 64> lines;
- fileBuf->getBuffer().split(lines, "\n");
+ fileBuf.get()->getBuffer().split(lines, "\n");
for (unsigned idx = 0; idx+3 <= lines.size(); idx += 3) {
StringRef fromFilename = lines[idx];
@@ -112,8 +112,7 @@ bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
bool FileRemapper::flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag) {
using namespace llvm::sys;
- bool existed;
- if (fs::create_directory(outputDir, existed) != llvm::errc::success)
+ if (fs::create_directory(outputDir))
return report("Could not create directory: " + outputDir, Diag);
std::string infoFile = getRemapInfoFile(outputDir);
@@ -125,8 +124,7 @@ bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) {
std::string errMsg;
std::string infoFile = outputPath;
- llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg,
- llvm::sys::fs::F_Binary);
+ llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg, llvm::sys::fs::F_None);
if (!errMsg.empty())
return report(errMsg, Diag);
@@ -182,8 +180,7 @@ bool FileRemapper::overwriteOriginal(DiagnosticsEngine &Diag,
Diag);
std::string errMsg;
- llvm::raw_fd_ostream Out(origFE->getName(), errMsg,
- llvm::sys::fs::F_Binary);
+ llvm::raw_fd_ostream Out(origFE->getName(), errMsg, llvm::sys::fs::F_None);
if (!errMsg.empty())
return report(errMsg, Diag);
@@ -210,22 +207,6 @@ void FileRemapper::applyMappings(PreprocessorOptions &PPOpts) const {
PPOpts.RetainRemappedFileBuffers = true;
}
-void FileRemapper::transferMappingsAndClear(PreprocessorOptions &PPOpts) {
- for (MappingsTy::iterator
- I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
- if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
- PPOpts.addRemappedFile(I->first->getName(), FE->getName());
- } else {
- llvm::MemoryBuffer *mem = I->second.get<llvm::MemoryBuffer *>();
- PPOpts.addRemappedFile(I->first->getName(), mem);
- }
- I->second = Target();
- }
-
- PPOpts.RetainRemappedFileBuffers = false;
- clear();
-}
-
void FileRemapper::remap(StringRef filePath, llvm::MemoryBuffer *memBuf) {
remap(getOriginalFile(filePath), memBuf);
}
@@ -272,9 +253,7 @@ void FileRemapper::resetTarget(Target &targ) {
}
bool FileRemapper::report(const Twine &err, DiagnosticsEngine &Diag) {
- SmallString<128> buf;
- unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
- err.toStringRef(buf));
- Diag.Report(ID);
+ Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+ << err.str();
return true;
}
diff --git a/lib/ARCMigrate/Internals.h b/lib/ARCMigrate/Internals.h
index 3690c83d8457..a65b329c5b03 100644
--- a/lib/ARCMigrate/Internals.h
+++ b/lib/ARCMigrate/Internals.h
@@ -48,7 +48,6 @@ void writeARCDiagsToPlist(const std::string &outPath,
class TransformActions {
DiagnosticsEngine &Diags;
CapturedDiagList &CapturedDiags;
- bool ReportedErrors;
void *Impl; // TransformActionsImpl.
public:
@@ -95,6 +94,8 @@ public:
return CapturedDiags.hasDiagnostic(IDs, range);
}
+ DiagnosticBuilder report(SourceLocation loc, unsigned diagId,
+ SourceRange range = SourceRange());
void reportError(StringRef error, SourceLocation loc,
SourceRange range = SourceRange());
void reportWarning(StringRef warning, SourceLocation loc,
@@ -102,7 +103,9 @@ public:
void reportNote(StringRef note, SourceLocation loc,
SourceRange range = SourceRange());
- bool hasReportedErrors() const { return ReportedErrors; }
+ bool hasReportedErrors() const {
+ return Diags.hasUnrecoverableErrorOccurred();
+ }
class RewriteReceiver {
public:
@@ -161,8 +164,6 @@ public:
const CapturedDiagList &getDiags() const { return CapturedDiags; }
bool isGCMigration() const { return OrigGCMode != LangOptions::NonGC; }
- bool noNSAllocReallocError() const { return MigOptions.NoNSAllocReallocError; }
- void setNSAllocReallocError(bool val) { MigOptions.NoNSAllocReallocError = val; }
bool noFinalizeRemoval() const { return MigOptions.NoFinalizeRemoval; }
void setNoFinalizeRemoval(bool val) {MigOptions.NoFinalizeRemoval = val; }
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index cac0fb0aed1b..1a2055e9c452 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -8,12 +8,15 @@
//===----------------------------------------------------------------------===//
#include "Transforms.h"
+#include "clang/ARCMigrate/ARCMT.h"
#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/NSAPI.h"
#include "clang/AST/ParentMap.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/Basic/FileManager.h"
#include "clang/Edit/Commit.h"
#include "clang/Edit/EditedSource.h"
@@ -24,11 +27,11 @@
#include "clang/Lex/PPConditionalDirectiveRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
#include "clang/StaticAnalyzer/Checkers/ObjCRetainCount.h"
-#include "clang/AST/Attr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
using namespace clang;
using namespace arcmt;
@@ -45,7 +48,6 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
void migrateDecl(Decl *D);
void migrateObjCInterfaceDecl(ASTContext &Ctx, ObjCContainerDecl *D);
- void migrateDeprecatedAnnotation(ASTContext &Ctx, ObjCCategoryDecl *CatDecl);
void migrateProtocolConformance(ASTContext &Ctx,
const ObjCImplementationDecl *ImpDecl);
void CacheObjCNSIntegerTypedefed(const TypedefDecl *TypedefDcl);
@@ -76,14 +78,18 @@ class ObjCMigrateASTConsumer : public ASTConsumer {
void migrateAddMethodAnnotation(ASTContext &Ctx,
const ObjCMethodDecl *MethodDecl);
+
+ void inferDesignatedInitializers(ASTContext &Ctx,
+ const ObjCImplementationDecl *ImplD);
+
public:
std::string MigrateDir;
unsigned ASTMigrateActions;
FileID FileId;
const TypedefDecl *NSIntegerTypedefed;
const TypedefDecl *NSUIntegerTypedefed;
- OwningPtr<NSAPI> NSAPIObj;
- OwningPtr<edit::EditedSource> Editor;
+ std::unique_ptr<NSAPI> NSAPIObj;
+ std::unique_ptr<edit::EditedSource> Editor;
FileRemapper &Remapper;
FileManager &FileMgr;
const PPConditionalDirectiveRecord *PPRec;
@@ -103,7 +109,7 @@ public:
ArrayRef<std::string> WhiteList)
: MigrateDir(migrateDir),
ASTMigrateActions(astMigrateActions),
- NSIntegerTypedefed(0), NSUIntegerTypedefed(0),
+ NSIntegerTypedefed(nullptr), NSUIntegerTypedefed(nullptr),
Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec), PP(PP),
IsOutputFile(isOutputFile) {
@@ -114,26 +120,26 @@ public:
}
protected:
- virtual void Initialize(ASTContext &Context) {
+ void Initialize(ASTContext &Context) override {
NSAPIObj.reset(new NSAPI(Context));
Editor.reset(new edit::EditedSource(Context.getSourceManager(),
Context.getLangOpts(),
- PPRec, false));
+ PPRec));
}
- virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+ bool HandleTopLevelDecl(DeclGroupRef DG) override {
for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
migrateDecl(*I);
return true;
}
- virtual void HandleInterestingDecl(DeclGroupRef DG) {
+ void HandleInterestingDecl(DeclGroupRef DG) override {
// Ignore decls from the PCH.
}
- virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
+ void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override {
ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
}
- virtual void HandleTranslationUnit(ASTContext &Ctx);
+ void HandleTranslationUnit(ASTContext &Ctx) override;
bool canModifyFile(StringRef Path) {
if (WhiteListFilenames.empty())
@@ -141,6 +147,30 @@ protected:
return WhiteListFilenames.find(llvm::sys::path::filename(Path))
!= WhiteListFilenames.end();
}
+ bool canModifyFile(const FileEntry *FE) {
+ if (!FE)
+ return false;
+ return canModifyFile(FE->getName());
+ }
+ bool canModifyFile(FileID FID) {
+ if (FID.isInvalid())
+ return false;
+ return canModifyFile(PP.getSourceManager().getFileEntryForID(FID));
+ }
+
+ bool canModify(const Decl *D) {
+ if (!D)
+ return false;
+ if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(D))
+ return canModify(CatImpl->getCategoryDecl());
+ if (const ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D))
+ return canModify(Impl->getClassInterface());
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
+ return canModify(cast<Decl>(MD->getDeclContext()));
+
+ FileID FID = PP.getSourceManager().getFileID(D->getLocation());
+ return canModifyFile(FID);
+ }
};
}
@@ -150,7 +180,7 @@ ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
unsigned migrateAction)
: WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
ObjCMigAction(migrateAction),
- CompInst(0) {
+ CompInst(nullptr) {
if (MigrateDir.empty())
MigrateDir = "."; // user current directory if none is given.
}
@@ -223,7 +253,7 @@ public:
class BodyMigrator : public RecursiveASTVisitor<BodyMigrator> {
ObjCMigrateASTConsumer &Consumer;
- OwningPtr<ParentMap> PMap;
+ std::unique_ptr<ParentMap> PMap;
public:
BodyMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
@@ -294,7 +324,9 @@ void MigrateBlockOrFunctionPointerTypeVariable(std::string & PropertyString,
static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType) {
Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
bool RetainableObject = ArgType->isObjCRetainableType();
- if (RetainableObject && propertyLifetime == Qualifiers::OCL_Strong) {
+ if (RetainableObject &&
+ (propertyLifetime == Qualifiers::OCL_Strong
+ || propertyLifetime == Qualifiers::OCL_None)) {
if (const ObjCObjectPointerType *ObjPtrTy =
ArgType->getAs<ObjCObjectPointerType>()) {
ObjCInterfaceDecl *IDecl = ObjPtrTy->getObjectType()->getInterface();
@@ -302,7 +334,7 @@ static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType
IDecl->lookupNestedProtocol(&Context.Idents.get("NSCopying")))
return "copy";
else
- return "retain";
+ return "strong";
}
else if (ArgType->isBlockPointerType())
return "copy";
@@ -311,8 +343,8 @@ static const char *PropertyMemoryAttribute(ASTContext &Context, QualType ArgType
// looking into setter's implementation for backing weak ivar.
return "weak";
else if (RetainableObject)
- return ArgType->isBlockPointerType() ? "copy" : "retain";
- return 0;
+ return ArgType->isBlockPointerType() ? "copy" : "strong";
+ return nullptr;
}
static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
@@ -344,23 +376,23 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
PropertyString += PropertyNameString;
}
// Property with no setter may be suggested as a 'readonly' property.
- if (!Setter) {
+ if (!Setter)
append_attr(PropertyString, "readonly", LParenAdded);
- QualType ResType = Context.getCanonicalType(Getter->getResultType());
- if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType))
- append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
- }
+
// Short circuit 'delegate' properties that contain the name "delegate" or
// "dataSource", or have exact name "target" to have 'assign' attribute.
if (PropertyName.equals("target") ||
(PropertyName.find("delegate") != StringRef::npos) ||
(PropertyName.find("dataSource") != StringRef::npos)) {
- QualType QT = Getter->getResultType();
+ QualType QT = Getter->getReturnType();
if (!QT->isRealType())
append_attr(PropertyString, "assign", LParenAdded);
- }
- else if (Setter) {
+ } else if (!Setter) {
+ QualType ResType = Context.getCanonicalType(Getter->getReturnType());
+ if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ResType))
+ append_attr(PropertyString, MemoryManagementAttr, LParenAdded);
+ } else {
const ParmVarDecl *argDecl = *Setter->param_begin();
QualType ArgType = Context.getCanonicalType(argDecl->getType());
if (const char *MemoryManagementAttr = PropertyMemoryAttribute(Context, ArgType))
@@ -368,7 +400,7 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
}
if (LParenAdded)
PropertyString += ')';
- QualType RT = Getter->getResultType();
+ QualType RT = Getter->getReturnType();
if (!isa<TypedefType>(RT)) {
// strip off any ARC lifetime qualifier.
QualType CanResultTy = Context.getCanonicalType(RT);
@@ -419,21 +451,27 @@ static void rewriteToObjCProperty(const ObjCMethodDecl *Getter,
// Get location past ';'
EndLoc = EndLoc.getLocWithOffset(1);
SourceLocation BeginOfSetterDclLoc = Setter->getLocStart();
- // FIXME. This assumes that setter decl; is immediately preceeded by eoln.
+ // FIXME. This assumes that setter decl; is immediately preceded by eoln.
// It is trying to remove the setter method decl. line entirely.
BeginOfSetterDclLoc = BeginOfSetterDclLoc.getLocWithOffset(-1);
commit.remove(SourceRange(BeginOfSetterDclLoc, EndLoc));
}
}
+static bool IsCategoryNameWithDeprecatedSuffix(ObjCContainerDecl *D) {
+ if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(D)) {
+ StringRef Name = CatDecl->getName();
+ return Name.endswith("Deprecated");
+ }
+ return false;
+}
+
void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
ObjCContainerDecl *D) {
- if (D->isDeprecated())
+ if (D->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(D))
return;
-
- for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
- M != MEnd; ++M) {
- ObjCMethodDecl *Method = (*M);
+
+ for (auto *Method : D->methods()) {
if (Method->isDeprecated())
continue;
bool PropertyInferred = migrateProperty(Ctx, D, Method);
@@ -448,48 +486,13 @@ void ObjCMigrateASTConsumer::migrateObjCInterfaceDecl(ASTContext &Ctx,
if (!(ASTMigrateActions & FrontendOptions::ObjCMT_ReturnsInnerPointerProperty))
return;
- for (ObjCContainerDecl::prop_iterator P = D->prop_begin(),
- E = D->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = *P;
+ for (auto *Prop : D->properties()) {
if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
!Prop->isDeprecated())
migratePropertyNsReturnsInnerPointer(Ctx, Prop);
}
}
-void ObjCMigrateASTConsumer::migrateDeprecatedAnnotation(ASTContext &Ctx,
- ObjCCategoryDecl *CatDecl) {
- StringRef Name = CatDecl->getName();
- if (!Name.endswith("Deprecated"))
- return;
-
- if (!Ctx.Idents.get("DEPRECATED").hasMacroDefinition())
- return;
-
- ObjCContainerDecl *D = cast<ObjCContainerDecl>(CatDecl);
-
- for (ObjCContainerDecl::method_iterator M = D->meth_begin(), MEnd = D->meth_end();
- M != MEnd; ++M) {
- ObjCMethodDecl *Method = (*M);
- if (Method->isDeprecated() || Method->isImplicit())
- continue;
- // Annotate with DEPRECATED
- edit::Commit commit(*Editor);
- commit.insertBefore(Method->getLocEnd(), " DEPRECATED");
- Editor->commit(commit);
- }
- for (ObjCContainerDecl::prop_iterator P = D->prop_begin(),
- E = D->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Prop = *P;
- if (Prop->isDeprecated())
- continue;
- // Annotate with DEPRECATED
- edit::Commit commit(*Editor);
- commit.insertAfterToken(Prop->getLocEnd(), " DEPRECATED");
- Editor->commit(commit);
- }
-}
-
static bool
ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
const ObjCImplementationDecl *ImpDecl,
@@ -500,9 +503,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
// in class interface.
bool HasAtleastOneRequiredProperty = false;
if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition())
- for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(),
- E = PDecl->prop_end(); P != E; ++P) {
- ObjCPropertyDecl *Property = *P;
+ for (const auto *Property : PDecl->properties()) {
if (Property->getPropertyImplementation() == ObjCPropertyDecl::Optional)
continue;
HasAtleastOneRequiredProperty = true;
@@ -532,9 +533,7 @@ ClassImplementsAllMethodsAndProperties(ASTContext &Ctx,
if (const ObjCProtocolDecl *PDecl = Protocol->getDefinition()) {
if (PDecl->meth_begin() == PDecl->meth_end())
return HasAtleastOneRequiredProperty;
- for (ObjCContainerDecl::method_iterator M = PDecl->meth_begin(),
- MEnd = PDecl->meth_end(); M != MEnd; ++M) {
- ObjCMethodDecl *MD = (*M);
+ for (const auto *MD : PDecl->methods()) {
if (MD->isImplicit())
continue;
if (MD->getImplementationControl() == ObjCMethodDecl::Optional)
@@ -632,7 +631,7 @@ static bool rewriteToNSEnumDecl(const EnumDecl *EnumDcl,
/*IsDecl*/true);
if (!EndOfEnumDclLoc.isInvalid()) {
SourceLocation BeginOfEnumDclLoc = EnumDcl->getLocStart();
- // FIXME. This assumes that enum decl; is immediately preceeded by eoln.
+ // FIXME. This assumes that enum decl; is immediately preceded by eoln.
// It is trying to remove the enum decl. lines entirely.
BeginOfEnumDclLoc = BeginOfEnumDclLoc.getLocWithOffset(-1);
commit.remove(SourceRange(BeginOfEnumDclLoc, EndOfEnumDclLoc));
@@ -660,9 +659,7 @@ static bool UseNSOptionsMacro(Preprocessor &PP, ASTContext &Ctx,
bool PowerOfTwo = true;
bool AllHexdecimalEnumerator = true;
uint64_t MaxPowerOfTwoVal = 0;
- for (EnumDecl::enumerator_iterator EI = EnumDcl->enumerator_begin(),
- EE = EnumDcl->enumerator_end(); EI != EE; ++EI) {
- EnumConstantDecl *Enumerator = (*EI);
+ for (auto Enumerator : EnumDcl->enumerators()) {
const Expr *InitExpr = Enumerator->getInitExpr();
if (!InitExpr) {
PowerOfTwo = false;
@@ -749,6 +746,8 @@ void ObjCMigrateASTConsumer::migrateProtocolConformance(ASTContext &Ctx,
if (!DropIt)
MinimalConformingProtocols.push_back(TargetPDecl);
}
+ if (MinimalConformingProtocols.empty())
+ return;
edit::Commit commit(*Editor);
rewriteToObjCInterfaceDecl(IDecl, MinimalConformingProtocols,
*NSAPIObj, commit);
@@ -774,11 +773,11 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
if (!TypedefDcl) {
if (NSIntegerTypedefed) {
TypedefDcl = NSIntegerTypedefed;
- NSIntegerTypedefed = 0;
+ NSIntegerTypedefed = nullptr;
}
else if (NSUIntegerTypedefed) {
TypedefDcl = NSUIntegerTypedefed;
- NSUIntegerTypedefed = 0;
+ NSUIntegerTypedefed = nullptr;
}
else
return false;
@@ -831,11 +830,15 @@ bool ObjCMigrateASTConsumer::migrateNSEnumDecl(ASTContext &Ctx,
return Res;
}
-static void ReplaceWithInstancetype(const ObjCMigrateASTConsumer &ASTC,
+static void ReplaceWithInstancetype(ASTContext &Ctx,
+ const ObjCMigrateASTConsumer &ASTC,
ObjCMethodDecl *OM) {
+ if (OM->getReturnType() == Ctx.getObjCInstanceType())
+ return; // already has instancetype.
+
SourceRange R;
std::string ClassString;
- if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) {
+ if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
TypeLoc TL = TSInfo->getTypeLoc();
R = SourceRange(TL.getBeginLoc(), TL.getEndLoc());
ClassString = "instancetype";
@@ -855,7 +858,7 @@ static void ReplaceWithClasstype(const ObjCMigrateASTConsumer &ASTC,
ObjCInterfaceDecl *IDecl = OM->getClassInterface();
SourceRange R;
std::string ClassString;
- if (TypeSourceInfo *TSInfo = OM->getResultTypeSourceInfo()) {
+ if (TypeSourceInfo *TSInfo = OM->getReturnTypeSourceInfo()) {
TypeLoc TL = TSInfo->getTypeLoc();
R = SourceRange(TL.getBeginLoc(), TL.getEndLoc()); {
ClassString = IDecl->getName();
@@ -893,14 +896,14 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
migrateFactoryMethod(Ctx, CDecl, OM, OIT_Singleton);
return;
case OIT_Init:
- if (OM->getResultType()->isObjCIdType())
- ReplaceWithInstancetype(*this, OM);
+ if (OM->getReturnType()->isObjCIdType())
+ ReplaceWithInstancetype(Ctx, *this, OM);
return;
case OIT_ReturnsSelf:
migrateFactoryMethod(Ctx, CDecl, OM, OIT_ReturnsSelf);
return;
}
- if (!OM->getResultType()->isObjCIdType())
+ if (!OM->getReturnType()->isObjCIdType())
return;
ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(CDecl);
@@ -915,7 +918,7 @@ void ObjCMigrateASTConsumer::migrateMethodInstanceType(ASTContext &Ctx,
migrateFactoryMethod(Ctx, CDecl, OM);
return;
}
- ReplaceWithInstancetype(*this, OM);
+ ReplaceWithInstancetype(Ctx, *this, OM);
}
static bool TypeIsInnerPointer(QualType T) {
@@ -1034,7 +1037,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
Method->param_size() != 0)
return false;
// Is this method candidate to be a getter?
- QualType GRT = Method->getResultType();
+ QualType GRT = Method->getReturnType();
if (GRT->isVoidType())
return false;
@@ -1087,7 +1090,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
return false;
// Is this a valid setter, matching the target getter?
- QualType SRT = SetterMethod->getResultType();
+ QualType SRT = SetterMethod->getReturnType();
if (!SRT->isVoidType())
return false;
const ParmVarDecl *argDecl = *SetterMethod->param_begin();
@@ -1109,7 +1112,7 @@ bool ObjCMigrateASTConsumer::migrateProperty(ASTContext &Ctx,
// Try a non-void method with no argument (and no setter or property of same name
// as a 'readonly' property.
edit::Commit commit(*Editor);
- rewriteToObjCProperty(Method, 0 /*SetterMethod*/, *NSAPIObj, commit,
+ rewriteToObjCProperty(Method, nullptr /*SetterMethod*/, *NSAPIObj, commit,
LengthOfPrefix,
(ASTMigrateActions &
FrontendOptions::ObjCMT_AtomicProperty) != 0,
@@ -1128,8 +1131,8 @@ void ObjCMigrateASTConsumer::migrateNsReturnsInnerPointer(ASTContext &Ctx,
!OM->isInstanceMethod() ||
OM->hasAttr<ObjCReturnsInnerPointerAttr>())
return;
-
- QualType RT = OM->getResultType();
+
+ QualType RT = OM->getReturnType();
if (!TypeIsInnerPointer(RT) ||
!Ctx.Idents.get("NS_RETURNS_INNER_POINTER").hasMacroDefinition())
return;
@@ -1153,14 +1156,11 @@ void ObjCMigrateASTConsumer::migratePropertyNsReturnsInnerPointer(ASTContext &Ct
void ObjCMigrateASTConsumer::migrateAllMethodInstaceType(ASTContext &Ctx,
ObjCContainerDecl *CDecl) {
- if (CDecl->isDeprecated())
+ if (CDecl->isDeprecated() || IsCategoryNameWithDeprecatedSuffix(CDecl))
return;
// migrate methods which can have instancetype as their result type.
- for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
- MEnd = CDecl->meth_end();
- M != MEnd; ++M) {
- ObjCMethodDecl *Method = (*M);
+ for (auto *Method : CDecl->methods()) {
if (Method->isDeprecated())
continue;
migrateMethodInstanceType(Ctx, CDecl, Method);
@@ -1172,8 +1172,8 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
ObjCMethodDecl *OM,
ObjCInstanceTypeFamily OIT_Family) {
if (OM->isInstanceMethod() ||
- OM->getResultType() == Ctx.getObjCInstanceType() ||
- !OM->getResultType()->isObjCIdType())
+ OM->getReturnType() == Ctx.getObjCInstanceType() ||
+ !OM->getReturnType()->isObjCIdType())
return;
// Candidate factory methods are + (id) NaMeXXX : ... which belong to a class
@@ -1228,7 +1228,7 @@ void ObjCMigrateASTConsumer::migrateFactoryMethod(ASTContext &Ctx,
if (OIT_Family == OIT_ReturnsSelf)
ReplaceWithClasstype(*this, OM);
else
- ReplaceWithInstancetype(*this, OM);
+ ReplaceWithInstancetype(Ctx, *this, OM);
}
static bool IsVoidStarType(QualType Ty) {
@@ -1338,7 +1338,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
// Annotate function.
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
- const char *AnnotationString = 0;
+ const char *AnnotationString = nullptr;
if (Ret.getObjKind() == RetEffect::CF) {
if (Ret.isOwned() &&
Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
@@ -1359,19 +1359,19 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+ 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];
- if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
+ if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
Editor->commit(commit);
}
- else if (AE == DecRefMsg && !pd->getAttr<NSConsumedAttr>() &&
+ else if (AE == DecRefMsg && !pd->hasAttr<NSConsumedAttr>() &&
Ctx.Idents.get("NS_CONSUMED").hasMacroDefinition()) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "NS_CONSUMED ");
@@ -1389,11 +1389,11 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
return CF_BRIDGING_NONE;
CallEffects CE = CallEffects::getEffect(FuncDecl);
- bool FuncIsReturnAnnotated = (FuncDecl->getAttr<CFReturnsRetainedAttr>() ||
- FuncDecl->getAttr<CFReturnsNotRetainedAttr>() ||
- FuncDecl->getAttr<NSReturnsRetainedAttr>() ||
- FuncDecl->getAttr<NSReturnsNotRetainedAttr>() ||
- FuncDecl->getAttr<NSReturnsAutoreleasedAttr>());
+ bool FuncIsReturnAnnotated = (FuncDecl->hasAttr<CFReturnsRetainedAttr>() ||
+ FuncDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+ FuncDecl->hasAttr<NSReturnsRetainedAttr>() ||
+ FuncDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+ FuncDecl->hasAttr<NSReturnsAutoreleasedAttr>());
// Trivial case of when funciton is annotated and has no argument.
if (FuncIsReturnAnnotated && FuncDecl->getNumParams() == 0)
@@ -1405,13 +1405,13 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
if (Ret.getObjKind() == RetEffect::CF &&
(Ret.isOwned() || Ret.notOwned()))
ReturnCFAudited = true;
- else if (!AuditedType(FuncDecl->getResultType()))
+ else if (!AuditedType(FuncDecl->getReturnType()))
return CF_BRIDGING_NONE;
}
// At this point result type is audited for potential inclusion.
// Now, how about argument types.
- llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+ ArrayRef<ArgEffect> AEArgs = CE.getArgs();
unsigned i = 0;
bool ArgCFAudited = false;
for (FunctionDecl::param_const_iterator pi = FuncDecl->param_begin(),
@@ -1419,7 +1419,7 @@ ObjCMigrateASTConsumer::CF_BRIDGING_KIND
const ParmVarDecl *pd = *pi;
ArgEffect AE = AEArgs[i];
if (AE == DecRef /*CFConsumed annotated*/ || AE == IncRef) {
- if (AE == DecRef && !pd->getAttr<CFConsumedAttr>())
+ if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>())
ArgCFAudited = true;
else if (AE == IncRef)
ArgCFAudited = true;
@@ -1444,12 +1444,8 @@ void ObjCMigrateASTConsumer::migrateARCSafeAnnotation(ASTContext &Ctx,
return;
// migrate methods which can have instancetype as their result type.
- for (ObjCContainerDecl::method_iterator M = CDecl->meth_begin(),
- MEnd = CDecl->meth_end();
- M != MEnd; ++M) {
- ObjCMethodDecl *Method = (*M);
+ for (const auto *Method : CDecl->methods())
migrateCFAnnotation(Ctx, Method);
- }
}
void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
@@ -1459,7 +1455,7 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
// Annotate function.
if (!ResultAnnotated) {
RetEffect Ret = CE.getReturnValue();
- const char *AnnotationString = 0;
+ const char *AnnotationString = nullptr;
if (Ret.getObjKind() == RetEffect::CF) {
if (Ret.isOwned() &&
Ctx.Idents.get("CF_RETURNS_RETAINED").hasMacroDefinition())
@@ -1492,13 +1488,13 @@ void ObjCMigrateASTConsumer::AddCFAnnotations(ASTContext &Ctx,
Editor->commit(commit);
}
}
- llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+ 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];
- if (AE == DecRef && !pd->getAttr<CFConsumedAttr>() &&
+ if (AE == DecRef && !pd->hasAttr<CFConsumedAttr>() &&
Ctx.Idents.get("CF_CONSUMED").hasMacroDefinition()) {
edit::Commit commit(*Editor);
commit.insertBefore(pd->getLocation(), "CF_CONSUMED ");
@@ -1514,14 +1510,14 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
return;
CallEffects CE = CallEffects::getEffect(MethodDecl);
- bool MethodIsReturnAnnotated = (MethodDecl->getAttr<CFReturnsRetainedAttr>() ||
- MethodDecl->getAttr<CFReturnsNotRetainedAttr>() ||
- MethodDecl->getAttr<NSReturnsRetainedAttr>() ||
- MethodDecl->getAttr<NSReturnsNotRetainedAttr>() ||
- MethodDecl->getAttr<NSReturnsAutoreleasedAttr>());
+ bool MethodIsReturnAnnotated = (MethodDecl->hasAttr<CFReturnsRetainedAttr>() ||
+ MethodDecl->hasAttr<CFReturnsNotRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsNotRetainedAttr>() ||
+ MethodDecl->hasAttr<NSReturnsAutoreleasedAttr>());
if (CE.getReceiver() == DecRefMsg &&
- !MethodDecl->getAttr<NSConsumesSelfAttr>() &&
+ !MethodDecl->hasAttr<NSConsumesSelfAttr>() &&
MethodDecl->getMethodFamily() != OMF_init &&
MethodDecl->getMethodFamily() != OMF_release &&
Ctx.Idents.get("NS_CONSUMES_SELF").hasMacroDefinition()) {
@@ -1542,20 +1538,19 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
(Ret.isOwned() || Ret.notOwned())) {
AddCFAnnotations(Ctx, CE, MethodDecl, false);
return;
- }
- else if (!AuditedType(MethodDecl->getResultType()))
+ } else if (!AuditedType(MethodDecl->getReturnType()))
return;
}
// At this point result type is either annotated or audited.
// Now, how about argument types.
- llvm::ArrayRef<ArgEffect> AEArgs = CE.getArgs();
+ 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];
- if ((AE == DecRef && !pd->getAttr<CFConsumedAttr>()) || AE == IncRef ||
+ if ((AE == DecRef && !pd->hasAttr<CFConsumedAttr>()) || AE == IncRef ||
!AuditedType(pd->getType())) {
AddCFAnnotations(Ctx, CE, MethodDecl, MethodIsReturnAnnotated);
return;
@@ -1565,6 +1560,53 @@ void ObjCMigrateASTConsumer::migrateAddMethodAnnotation(
}
namespace {
+class SuperInitChecker : public RecursiveASTVisitor<SuperInitChecker> {
+public:
+ bool shouldVisitTemplateInstantiations() const { return false; }
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
+ if (E->getMethodFamily() == OMF_init)
+ return false;
+ }
+ return true;
+ }
+};
+} // anonymous namespace
+
+static bool hasSuperInitCall(const ObjCMethodDecl *MD) {
+ return !SuperInitChecker().TraverseStmt(MD->getBody());
+}
+
+void ObjCMigrateASTConsumer::inferDesignatedInitializers(
+ ASTContext &Ctx,
+ const ObjCImplementationDecl *ImplD) {
+
+ const ObjCInterfaceDecl *IFace = ImplD->getClassInterface();
+ if (!IFace || IFace->hasDesignatedInitializers())
+ return;
+ if (!Ctx.Idents.get("NS_DESIGNATED_INITIALIZER").hasMacroDefinition())
+ return;
+
+ for (const auto *MD : ImplD->instance_methods()) {
+ if (MD->isDeprecated() ||
+ MD->getMethodFamily() != OMF_init ||
+ MD->isDesignatedInitializerForTheInterface())
+ continue;
+ const ObjCMethodDecl *IFaceM = IFace->getMethod(MD->getSelector(),
+ /*isInstance=*/true);
+ if (!IFaceM)
+ continue;
+ if (hasSuperInitCall(MD)) {
+ edit::Commit commit(*Editor);
+ commit.insert(IFaceM->getLocEnd(), " NS_DESIGNATED_INITIALIZER");
+ Editor->commit(commit);
+ }
+ }
+}
+
+namespace {
class RewritesReceiver : public edit::EditsReceiver {
Rewriter &Rewrite;
@@ -1572,42 +1614,92 @@ class RewritesReceiver : public edit::EditsReceiver {
public:
RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
- virtual void insert(SourceLocation loc, StringRef text) {
+ void insert(SourceLocation loc, StringRef text) override {
Rewrite.InsertText(loc, text);
}
- virtual void replace(CharSourceRange range, StringRef text) {
+ void replace(CharSourceRange range, StringRef text) override {
Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
}
};
-}
+class JSONEditWriter : public edit::EditsReceiver {
+ SourceManager &SourceMgr;
+ llvm::raw_ostream &OS;
-static bool
-IsReallyASystemHeader(ASTContext &Ctx, const FileEntry *file, FileID FID) {
- bool Invalid = false;
- const SrcMgr::SLocEntry &SEntry =
- Ctx.getSourceManager().getSLocEntry(FID, &Invalid);
- if (!Invalid && SEntry.isFile()) {
- const SrcMgr::FileInfo &FI = SEntry.getFile();
- if (!FI.hasLineDirectives()) {
- if (FI.getFileCharacteristic() == SrcMgr::C_ExternCSystem)
- return true;
- if (FI.getFileCharacteristic() == SrcMgr::C_System) {
- // This file is in a system header directory. Continue with commiting change
- // only if it is a user specified system directory because user put a
- // .system_framework file in the framework directory.
- StringRef Directory(file->getDir()->getName());
- size_t Ix = Directory.rfind(".framework");
- if (Ix == StringRef::npos)
- return true;
- std::string PatchToSystemFramework = Directory.slice(0, Ix+sizeof(".framework"));
- PatchToSystemFramework += ".system_framework";
- if (!llvm::sys::fs::exists(PatchToSystemFramework.data()))
- return true;
- }
+public:
+ JSONEditWriter(SourceManager &SM, llvm::raw_ostream &OS)
+ : SourceMgr(SM), OS(OS) {
+ OS << "[\n";
+ }
+ ~JSONEditWriter() {
+ OS << "]\n";
+ }
+
+private:
+ struct EntryWriter {
+ SourceManager &SourceMgr;
+ llvm::raw_ostream &OS;
+
+ EntryWriter(SourceManager &SM, llvm::raw_ostream &OS)
+ : SourceMgr(SM), OS(OS) {
+ OS << " {\n";
+ }
+ ~EntryWriter() {
+ OS << " },\n";
}
+
+ void writeLoc(SourceLocation Loc) {
+ FileID FID;
+ unsigned Offset;
+ std::tie(FID, Offset) = SourceMgr.getDecomposedLoc(Loc);
+ assert(!FID.isInvalid());
+ SmallString<200> Path =
+ StringRef(SourceMgr.getFileEntryForID(FID)->getName());
+ llvm::sys::fs::make_absolute(Path);
+ OS << " \"file\": \"";
+ OS.write_escaped(Path.str()) << "\",\n";
+ OS << " \"offset\": " << Offset << ",\n";
+ }
+
+ void writeRemove(CharSourceRange Range) {
+ assert(Range.isCharRange());
+ std::pair<FileID, unsigned> Begin =
+ SourceMgr.getDecomposedLoc(Range.getBegin());
+ std::pair<FileID, unsigned> End =
+ SourceMgr.getDecomposedLoc(Range.getEnd());
+ assert(Begin.first == End.first);
+ assert(Begin.second <= End.second);
+ unsigned Length = End.second - Begin.second;
+
+ OS << " \"remove\": " << Length << ",\n";
+ }
+
+ void writeText(StringRef Text) {
+ OS << " \"text\": \"";
+ OS.write_escaped(Text) << "\",\n";
+ }
+ };
+
+ void insert(SourceLocation Loc, StringRef Text) override {
+ EntryWriter Writer(SourceMgr, OS);
+ Writer.writeLoc(Loc);
+ Writer.writeText(Text);
}
- return false;
+
+ void replace(CharSourceRange Range, StringRef Text) override {
+ EntryWriter Writer(SourceMgr, OS);
+ Writer.writeLoc(Range.getBegin());
+ Writer.writeRemove(Range);
+ Writer.writeText(Text);
+ }
+
+ void remove(CharSourceRange Range) override {
+ EntryWriter Writer(SourceMgr, OS);
+ Writer.writeLoc(Range.getBegin());
+ Writer.writeRemove(Range);
+ }
+};
+
}
void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
@@ -1624,22 +1716,25 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
}
if (ObjCInterfaceDecl *CDecl = dyn_cast<ObjCInterfaceDecl>(*D))
- migrateObjCInterfaceDecl(Ctx, CDecl);
+ if (canModify(CDecl))
+ migrateObjCInterfaceDecl(Ctx, CDecl);
if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(*D)) {
- migrateObjCInterfaceDecl(Ctx, CatDecl);
- if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
- migrateDeprecatedAnnotation(Ctx, CatDecl);
+ if (canModify(CatDecl))
+ migrateObjCInterfaceDecl(Ctx, CatDecl);
}
else if (ObjCProtocolDecl *PDecl = dyn_cast<ObjCProtocolDecl>(*D))
- ObjCProtocolDecls.insert(PDecl);
+ ObjCProtocolDecls.insert(PDecl->getCanonicalDecl());
else if (const ObjCImplementationDecl *ImpDecl =
dyn_cast<ObjCImplementationDecl>(*D)) {
- if (ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance)
+ if ((ASTMigrateActions & FrontendOptions::ObjCMT_ProtocolConformance) &&
+ canModify(ImpDecl))
migrateProtocolConformance(Ctx, ImpDecl);
}
else if (const EnumDecl *ED = dyn_cast<EnumDecl>(*D)) {
if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
continue;
+ if (!canModify(ED))
+ continue;
DeclContext::decl_iterator N = D;
if (++N != DEnd) {
const TypedefDecl *TD = dyn_cast<TypedefDecl>(*N);
@@ -1647,11 +1742,13 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
D++;
}
else
- migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */0);
+ migrateNSEnumDecl(Ctx, ED, /*TypedefDecl */nullptr);
}
else if (const TypedefDecl *TD = dyn_cast<TypedefDecl>(*D)) {
if (!(ASTMigrateActions & FrontendOptions::ObjCMT_NsMacros))
continue;
+ if (!canModify(TD))
+ continue;
DeclContext::decl_iterator N = D;
if (++N == DEnd)
continue;
@@ -1673,23 +1770,49 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
CacheObjCNSIntegerTypedefed(TD);
}
else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*D)) {
- if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
+ if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
+ canModify(FD))
migrateCFAnnotation(Ctx, FD);
}
if (ObjCContainerDecl *CDecl = dyn_cast<ObjCContainerDecl>(*D)) {
+ bool CanModify = canModify(CDecl);
// migrate methods which can have instancetype as their result type.
- if (ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype)
+ if ((ASTMigrateActions & FrontendOptions::ObjCMT_Instancetype) &&
+ CanModify)
migrateAllMethodInstaceType(Ctx, CDecl);
// annotate methods with CF annotations.
- if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
+ if ((ASTMigrateActions & FrontendOptions::ObjCMT_Annotation) &&
+ CanModify)
migrateARCSafeAnnotation(Ctx, CDecl);
}
+
+ if (const ObjCImplementationDecl *
+ ImplD = dyn_cast<ObjCImplementationDecl>(*D)) {
+ if ((ASTMigrateActions & FrontendOptions::ObjCMT_DesignatedInitializer) &&
+ canModify(ImplD))
+ inferDesignatedInitializers(Ctx, ImplD);
+ }
}
if (ASTMigrateActions & FrontendOptions::ObjCMT_Annotation)
AnnotateImplicitBridging(Ctx);
}
+ if (IsOutputFile) {
+ std::string Error;
+ llvm::raw_fd_ostream OS(MigrateDir.c_str(), Error, llvm::sys::fs::F_None);
+ if (!Error.empty()) {
+ DiagnosticsEngine &Diags = Ctx.getDiagnostics();
+ Diags.Report(Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+ << Error;
+ return;
+ }
+
+ JSONEditWriter Writer(Ctx.getSourceManager(), OS);
+ Editor->applyRewrites(Writer);
+ return;
+ }
+
Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
RewritesReceiver Rec(rewriter);
Editor->applyRewrites(Rec);
@@ -1700,10 +1823,6 @@ void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
RewriteBuffer &buf = I->second;
const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
assert(file);
- if (IsReallyASystemHeader(Ctx, file, FID))
- continue;
- if (!canModifyFile(file->getName()))
- continue;
SmallString<512> newText;
llvm::raw_svector_ostream vecOS(newText);
buf.write(vecOS);
@@ -1734,8 +1853,8 @@ static std::vector<std::string> getWhiteListFilenames(StringRef DirPath) {
std::vector<std::string> Filenames;
if (DirPath.empty() || !is_directory(DirPath))
return Filenames;
-
- llvm::error_code EC;
+
+ std::error_code EC;
directory_iterator DI = directory_iterator(DirPath, EC);
directory_iterator DE;
for (; !EC && DI != DE; DI = DI.increment(EC)) {
@@ -1773,3 +1892,246 @@ ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
/*isOutputFile=*/true,
WhiteList);
}
+
+namespace {
+struct EditEntry {
+ const FileEntry *File;
+ unsigned Offset;
+ unsigned RemoveLen;
+ std::string Text;
+
+ EditEntry() : File(), Offset(), RemoveLen() {}
+};
+}
+
+namespace llvm {
+template<> struct DenseMapInfo<EditEntry> {
+ static inline EditEntry getEmptyKey() {
+ EditEntry Entry;
+ Entry.Offset = unsigned(-1);
+ return Entry;
+ }
+ static inline EditEntry getTombstoneKey() {
+ EditEntry Entry;
+ Entry.Offset = unsigned(-2);
+ return Entry;
+ }
+ static unsigned getHashValue(const EditEntry& Val) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Val.File);
+ ID.AddInteger(Val.Offset);
+ ID.AddInteger(Val.RemoveLen);
+ ID.AddString(Val.Text);
+ return ID.ComputeHash();
+ }
+ static bool isEqual(const EditEntry &LHS, const EditEntry &RHS) {
+ return LHS.File == RHS.File &&
+ LHS.Offset == RHS.Offset &&
+ LHS.RemoveLen == RHS.RemoveLen &&
+ LHS.Text == RHS.Text;
+ }
+};
+}
+
+namespace {
+class RemapFileParser {
+ FileManager &FileMgr;
+
+public:
+ RemapFileParser(FileManager &FileMgr) : FileMgr(FileMgr) { }
+
+ bool parse(StringRef File, SmallVectorImpl<EditEntry> &Entries) {
+ using namespace llvm::yaml;
+
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
+ llvm::MemoryBuffer::getFile(File);
+ if (!FileBufOrErr)
+ return true;
+
+ llvm::SourceMgr SM;
+ Stream YAMLStream(FileBufOrErr.get().release(), SM);
+ document_iterator I = YAMLStream.begin();
+ if (I == YAMLStream.end())
+ return true;
+ Node *Root = I->getRoot();
+ if (!Root)
+ return true;
+
+ SequenceNode *SeqNode = dyn_cast<SequenceNode>(Root);
+ if (!SeqNode)
+ return true;
+
+ for (SequenceNode::iterator
+ AI = SeqNode->begin(), AE = SeqNode->end(); AI != AE; ++AI) {
+ MappingNode *MapNode = dyn_cast<MappingNode>(&*AI);
+ if (!MapNode)
+ continue;
+ parseEdit(MapNode, Entries);
+ }
+
+ return false;
+ }
+
+private:
+ void parseEdit(llvm::yaml::MappingNode *Node,
+ SmallVectorImpl<EditEntry> &Entries) {
+ using namespace llvm::yaml;
+ EditEntry Entry;
+ bool Ignore = false;
+
+ for (MappingNode::iterator
+ KVI = Node->begin(), KVE = Node->end(); KVI != KVE; ++KVI) {
+ ScalarNode *KeyString = dyn_cast<ScalarNode>((*KVI).getKey());
+ if (!KeyString)
+ continue;
+ SmallString<10> KeyStorage;
+ StringRef Key = KeyString->getValue(KeyStorage);
+
+ ScalarNode *ValueString = dyn_cast<ScalarNode>((*KVI).getValue());
+ if (!ValueString)
+ continue;
+ SmallString<64> ValueStorage;
+ StringRef Val = ValueString->getValue(ValueStorage);
+
+ if (Key == "file") {
+ const FileEntry *FE = FileMgr.getFile(Val);
+ if (!FE)
+ Ignore = true;
+ Entry.File = FE;
+ } else if (Key == "offset") {
+ if (Val.getAsInteger(10, Entry.Offset))
+ Ignore = true;
+ } else if (Key == "remove") {
+ if (Val.getAsInteger(10, Entry.RemoveLen))
+ Ignore = true;
+ } else if (Key == "text") {
+ Entry.Text = Val;
+ }
+ }
+
+ if (!Ignore)
+ Entries.push_back(Entry);
+ }
+};
+}
+
+static bool reportDiag(const Twine &Err, DiagnosticsEngine &Diag) {
+ Diag.Report(Diag.getCustomDiagID(DiagnosticsEngine::Error, "%0"))
+ << Err.str();
+ return true;
+}
+
+static std::string applyEditsToTemp(const FileEntry *FE,
+ ArrayRef<EditEntry> Edits,
+ FileManager &FileMgr,
+ DiagnosticsEngine &Diag) {
+ using namespace llvm::sys;
+
+ SourceManager SM(Diag, FileMgr);
+ FileID FID = SM.createFileID(FE, SourceLocation(), SrcMgr::C_User);
+ LangOptions LangOpts;
+ edit::EditedSource Editor(SM, LangOpts);
+ for (ArrayRef<EditEntry>::iterator
+ I = Edits.begin(), E = Edits.end(); I != E; ++I) {
+ const EditEntry &Entry = *I;
+ assert(Entry.File == FE);
+ SourceLocation Loc =
+ SM.getLocForStartOfFile(FID).getLocWithOffset(Entry.Offset);
+ CharSourceRange Range;
+ if (Entry.RemoveLen != 0) {
+ Range = CharSourceRange::getCharRange(Loc,
+ Loc.getLocWithOffset(Entry.RemoveLen));
+ }
+
+ edit::Commit commit(Editor);
+ if (Range.isInvalid()) {
+ commit.insert(Loc, Entry.Text);
+ } else if (Entry.Text.empty()) {
+ commit.remove(Range);
+ } else {
+ commit.replace(Range, Entry.Text);
+ }
+ Editor.commit(commit);
+ }
+
+ Rewriter rewriter(SM, LangOpts);
+ RewritesReceiver Rec(rewriter);
+ Editor.applyRewrites(Rec);
+
+ const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID);
+ SmallString<512> NewText;
+ llvm::raw_svector_ostream OS(NewText);
+ Buf->write(OS);
+ OS.flush();
+
+ SmallString<64> TempPath;
+ int FD;
+ if (fs::createTemporaryFile(path::filename(FE->getName()),
+ path::extension(FE->getName()), FD,
+ TempPath)) {
+ reportDiag("Could not create file: " + TempPath.str(), Diag);
+ return std::string();
+ }
+
+ llvm::raw_fd_ostream TmpOut(FD, /*shouldClose=*/true);
+ TmpOut.write(NewText.data(), NewText.size());
+ TmpOut.close();
+
+ return TempPath.str();
+}
+
+bool arcmt::getFileRemappingsFromFileList(
+ std::vector<std::pair<std::string,std::string> > &remap,
+ ArrayRef<StringRef> remapFiles,
+ DiagnosticConsumer *DiagClient) {
+ bool hasErrorOccurred = false;
+
+ FileSystemOptions FSOpts;
+ FileManager FileMgr(FSOpts);
+ RemapFileParser Parser(FileMgr);
+
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+ IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+ new DiagnosticsEngine(DiagID, new DiagnosticOptions,
+ DiagClient, /*ShouldOwnClient=*/false));
+
+ typedef llvm::DenseMap<const FileEntry *, std::vector<EditEntry> >
+ FileEditEntriesTy;
+ FileEditEntriesTy FileEditEntries;
+
+ llvm::DenseSet<EditEntry> EntriesSet;
+
+ for (ArrayRef<StringRef>::iterator
+ I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
+ SmallVector<EditEntry, 16> Entries;
+ if (Parser.parse(*I, Entries))
+ continue;
+
+ for (SmallVectorImpl<EditEntry>::iterator
+ EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
+ EditEntry &Entry = *EI;
+ if (!Entry.File)
+ continue;
+ std::pair<llvm::DenseSet<EditEntry>::iterator, bool>
+ Insert = EntriesSet.insert(Entry);
+ if (!Insert.second)
+ continue;
+
+ FileEditEntries[Entry.File].push_back(Entry);
+ }
+ }
+
+ for (FileEditEntriesTy::iterator
+ I = FileEditEntries.begin(), E = FileEditEntries.end(); I != E; ++I) {
+ std::string TempFile = applyEditsToTemp(I->first, I->second,
+ FileMgr, *Diags);
+ if (TempFile.empty()) {
+ hasErrorOccurred = true;
+ continue;
+ }
+
+ remap.push_back(std::make_pair(I->first->getName(), TempFile));
+ }
+
+ return hasErrorOccurred;
+}
diff --git a/lib/ARCMigrate/PlistReporter.cpp b/lib/ARCMigrate/PlistReporter.cpp
index 144ba2e398ad..6b34ef0c2b9e 100644
--- a/lib/ARCMigrate/PlistReporter.cpp
+++ b/lib/ARCMigrate/PlistReporter.cpp
@@ -9,86 +9,27 @@
#include "Internals.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/PlistSupport.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
using namespace clang;
using namespace arcmt;
-
-// FIXME: This duplicates significant functionality from PlistDiagnostics.cpp,
-// it would be jolly good if there was a reusable PlistWriter or something.
-
-typedef llvm::DenseMap<FileID, unsigned> FIDMap;
-
-static void AddFID(FIDMap &FIDs, SmallVectorImpl<FileID> &V,
- const SourceManager &SM, SourceLocation L) {
-
- FileID FID = SM.getFileID(SM.getExpansionLoc(L));
- FIDMap::iterator I = FIDs.find(FID);
- if (I != FIDs.end()) return;
- FIDs[FID] = V.size();
- V.push_back(FID);
-}
-
-static unsigned GetFID(const FIDMap& FIDs, const SourceManager &SM,
- SourceLocation L) {
- FileID FID = SM.getFileID(SM.getExpansionLoc(L));
- FIDMap::const_iterator I = FIDs.find(FID);
- assert(I != FIDs.end());
- return I->second;
-}
-
-static raw_ostream& Indent(raw_ostream& o, const unsigned indent) {
- for (unsigned i = 0; i < indent; ++i) o << ' ';
- return o;
-}
-
-static void EmitLocation(raw_ostream& o, const SourceManager &SM,
- const LangOptions &LangOpts,
- SourceLocation L, const FIDMap &FM,
- unsigned indent, bool extend = false) {
-
- FullSourceLoc Loc(SM.getExpansionLoc(L), const_cast<SourceManager&>(SM));
-
- // Add in the length of the token, so that we cover multi-char tokens.
- unsigned offset =
- extend ? Lexer::MeasureTokenLength(Loc, SM, LangOpts) - 1 : 0;
-
- Indent(o, indent) << "<dict>\n";
- Indent(o, indent) << " <key>line</key><integer>"
- << Loc.getExpansionLineNumber() << "</integer>\n";
- Indent(o, indent) << " <key>col</key><integer>"
- << Loc.getExpansionColumnNumber() + offset << "</integer>\n";
- Indent(o, indent) << " <key>file</key><integer>"
- << GetFID(FM, SM, Loc) << "</integer>\n";
- Indent(o, indent) << "</dict>\n";
-}
-
-static void EmitRange(raw_ostream& o, const SourceManager &SM,
- const LangOptions &LangOpts,
- CharSourceRange R, const FIDMap &FM,
- unsigned indent) {
- Indent(o, indent) << "<array>\n";
- EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
- EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange());
- Indent(o, indent) << "</array>\n";
-}
-
-static raw_ostream& EmitString(raw_ostream& o,
- StringRef s) {
- o << "<string>";
- for (StringRef::const_iterator I=s.begin(), E=s.end(); I!=E; ++I) {
- char c = *I;
- switch (c) {
- default: o << c; break;
- case '&': o << "&amp;"; break;
- case '<': o << "&lt;"; break;
- case '>': o << "&gt;"; break;
- case '\'': o << "&apos;"; break;
- case '\"': o << "&quot;"; break;
- }
+using namespace markup;
+
+static StringRef getLevelName(DiagnosticsEngine::Level Level) {
+ switch (Level) {
+ case DiagnosticsEngine::Ignored:
+ llvm_unreachable("ignored");
+ case DiagnosticsEngine::Note:
+ return "note";
+ case DiagnosticsEngine::Remark:
+ case DiagnosticsEngine::Warning:
+ return "warning";
+ case DiagnosticsEngine::Fatal:
+ case DiagnosticsEngine::Error:
+ return "error";
}
- o << "</string>";
- return o;
+ llvm_unreachable("Invalid DiagnosticsEngine level!");
}
void arcmt::writeARCDiagsToPlist(const std::string &outPath,
@@ -116,17 +57,13 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
}
std::string errMsg;
- llvm::raw_fd_ostream o(outPath.c_str(), errMsg);
+ llvm::raw_fd_ostream o(outPath.c_str(), errMsg, llvm::sys::fs::F_Text);
if (!errMsg.empty()) {
llvm::errs() << "error: could not create file: " << outPath << '\n';
return;
}
- // Write the plist header.
- o << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" "
- "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
- "<plist version=\"1.0\">\n";
+ EmitPlistHeader(o);
// Write the root object: a <dict> containing...
// - "files", an <array> mapping from FIDs to file names
@@ -135,11 +72,8 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
" <key>files</key>\n"
" <array>\n";
- for (SmallVectorImpl<FileID>::iterator I=Fids.begin(), E=Fids.end();
- I!=E; ++I) {
- o << " ";
- EmitString(o, SM.getFileEntryForID(*I)->getName()) << '\n';
- }
+ for (FileID FID : Fids)
+ EmitString(o << " ", SM.getFileEntryForID(FID)->getName()) << '\n';
o << " </array>\n"
" <key>diagnostics</key>\n"
@@ -162,12 +96,7 @@ void arcmt::writeARCDiagsToPlist(const std::string &outPath,
EmitString(o, DiagIDs.getCategoryNameFromID(
DiagIDs.getCategoryNumberForDiag(D.getID()))) << '\n';
o << " <key>type</key>";
- if (D.getLevel() >= DiagnosticsEngine::Error)
- EmitString(o, "error") << '\n';
- else if (D.getLevel() == DiagnosticsEngine::Warning)
- EmitString(o, "warning") << '\n';
- else
- EmitString(o, "note") << '\n';
+ EmitString(o, getLevelName(D.getLevel())) << '\n';
// Output the location of the bug.
o << " <key>location</key>\n";
diff --git a/lib/ARCMigrate/TransAPIUses.cpp b/lib/ARCMigrate/TransAPIUses.cpp
index a0994a6b459a..544cb0addfcd 100644
--- a/lib/ARCMigrate/TransAPIUses.cpp
+++ b/lib/ARCMigrate/TransAPIUses.cpp
@@ -66,8 +66,7 @@ public:
selName = "getArgument";
else if (E->getSelector() == setArgumentSel)
selName = "setArgument";
-
- if (selName.empty())
+ else
return true;
Expr *parm = E->getArg(0)->IgnoreParenCasts();
@@ -75,13 +74,12 @@ public:
if (pointee.isNull())
return true;
- if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone) {
- std::string err = "NSInvocation's ";
- err += selName;
- err += " is not safe to be used with an object with ownership other "
- "than __unsafe_unretained";
- Pass.TA.reportError(err, parm->getLocStart(), parm->getSourceRange());
- }
+ if (pointee.getObjCLifetime() > Qualifiers::OCL_ExplicitNone)
+ Pass.TA.report(parm->getLocStart(),
+ diag::err_arcmt_nsinvocation_ownership,
+ parm->getSourceRange())
+ << selName;
+
return true;
}
diff --git a/lib/ARCMigrate/TransAutoreleasePool.cpp b/lib/ARCMigrate/TransAutoreleasePool.cpp
index a2990e7226ab..a8a99fa712a3 100644
--- a/lib/ARCMigrate/TransAutoreleasePool.cpp
+++ b/lib/ARCMigrate/TransAutoreleasePool.cpp
@@ -70,7 +70,7 @@ class AutoreleasePoolRewriter
: public RecursiveASTVisitor<AutoreleasePoolRewriter> {
public:
AutoreleasePoolRewriter(MigrationPass &pass)
- : Body(0), Pass(pass) {
+ : Body(nullptr), Pass(pass) {
PoolII = &pass.Ctx.Idents.get("NSAutoreleasePool");
DrainSel = pass.Ctx.Selectors.getNullarySelector(
&pass.Ctx.Idents.get("drain"));
@@ -230,7 +230,7 @@ private:
bool IsFollowedBySimpleReturnStmt;
SmallVector<ObjCMessageExpr *, 4> Releases;
- PoolScope() : PoolVar(0), CompoundParent(0), Begin(), End(),
+ PoolScope() : PoolVar(nullptr), CompoundParent(nullptr), Begin(), End(),
IsFollowedBySimpleReturnStmt(false) { }
SourceRange getIndentedRange() const {
@@ -305,7 +305,7 @@ private:
// statement, in which case we will include the return in the scope.
if (SI != SE)
if (ReturnStmt *retS = dyn_cast<ReturnStmt>(*SI))
- if ((retS->getRetValue() == 0 ||
+ if ((retS->getRetValue() == nullptr ||
isa<DeclRefExpr>(retS->getRetValue()->IgnoreParenCasts())) &&
findLocationAfterSemi(retS->getLocEnd(), Pass.Ctx).isValid()) {
scope.IsFollowedBySimpleReturnStmt = true;
@@ -421,7 +421,7 @@ private:
ExprSet Refs;
SmallVector<PoolScope, 2> Scopes;
- PoolVarInfo() : Dcl(0) { }
+ PoolVarInfo() : Dcl(nullptr) { }
};
std::map<VarDecl *, PoolVarInfo> PoolVars;
diff --git a/lib/ARCMigrate/TransBlockObjCVariable.cpp b/lib/ARCMigrate/TransBlockObjCVariable.cpp
index 97c4e3480c15..fac6a84c45e5 100644
--- a/lib/ARCMigrate/TransBlockObjCVariable.cpp
+++ b/lib/ARCMigrate/TransBlockObjCVariable.cpp
@@ -78,10 +78,9 @@ public:
bool VisitBlockDecl(BlockDecl *block) {
SmallVector<VarDecl *, 4> BlockVars;
- for (BlockDecl::capture_iterator
- I = block->capture_begin(), E = block->capture_end(); I != E; ++I) {
- VarDecl *var = I->getVariable();
- if (I->isByRef() &&
+ for (const auto &I : block->captures()) {
+ VarDecl *var = I.getVariable();
+ if (I.isByRef() &&
var->getType()->isObjCObjectPointerType() &&
isImplicitStrong(var->getType())) {
BlockVars.push_back(var);
diff --git a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index ffb638f8a306..9689f40760cd 100644
--- a/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -89,9 +89,8 @@ public:
bool VisitCompoundStmt(CompoundStmt *S) {
if (S->body_empty())
return false; // was already empty, not because of transformations.
- for (CompoundStmt::body_iterator
- I = S->body_begin(), E = S->body_end(); I != E; ++I)
- if (!Visit(*I))
+ for (auto *I : S->body())
+ if (!Visit(I))
return false;
return true;
}
@@ -167,9 +166,8 @@ public:
}
bool VisitCompoundStmt(CompoundStmt *S) {
- for (CompoundStmt::body_iterator
- I = S->body_begin(), E = S->body_end(); I != E; ++I)
- check(*I);
+ for (auto *I : S->body())
+ check(I);
return true;
}
@@ -189,9 +187,8 @@ private:
static bool isBodyEmpty(CompoundStmt *body, ASTContext &Ctx,
std::vector<SourceLocation> &MacroLocs) {
- for (CompoundStmt::body_iterator
- I = body->body_begin(), E = body->body_end(); I != E; ++I)
- if (!EmptyChecker(Ctx, MacroLocs).Visit(*I))
+ for (auto *I : body->body())
+ if (!EmptyChecker(Ctx, MacroLocs).Visit(I))
return false;
return true;
@@ -208,12 +205,9 @@ static void cleanupDeallocOrFinalize(MigrationPass &pass) {
impl_iterator;
for (impl_iterator I = impl_iterator(DC->decls_begin()),
E = impl_iterator(DC->decls_end()); I != E; ++I) {
- ObjCMethodDecl *DeallocM = 0;
- ObjCMethodDecl *FinalizeM = 0;
- for (ObjCImplementationDecl::instmeth_iterator
- MI = I->instmeth_begin(),
- ME = I->instmeth_end(); MI != ME; ++MI) {
- ObjCMethodDecl *MD = *MI;
+ ObjCMethodDecl *DeallocM = nullptr;
+ ObjCMethodDecl *FinalizeM = nullptr;
+ for (auto *MD : I->instance_methods()) {
if (!MD->hasBody())
continue;
diff --git a/lib/ARCMigrate/TransGCAttrs.cpp b/lib/ARCMigrate/TransGCAttrs.cpp
index d8be1ae746ab..10fce19b6f19 100644
--- a/lib/ARCMigrate/TransGCAttrs.cpp
+++ b/lib/ARCMigrate/TransGCAttrs.cpp
@@ -80,7 +80,7 @@ public:
}
}
- bool handleAttr(AttributedTypeLoc TL, Decl *D = 0) {
+ bool handleAttr(AttributedTypeLoc TL, Decl *D = nullptr) {
if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
return false;
@@ -134,8 +134,7 @@ public:
return hasObjCImpl(ContD);
if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
- for (CXXRecordDecl::method_iterator
- MI = RD->method_begin(), ME = RD->method_end(); MI != ME; ++MI) {
+ for (const auto *MI : RD->methods()) {
if (MI->isOutOfLine())
return true;
}
@@ -150,9 +149,9 @@ public:
return false;
if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D)) {
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ContD))
- return ID->getImplementation() != 0;
+ return ID->getImplementation() != nullptr;
if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD))
- return CD->getImplementation() != 0;
+ return CD->getImplementation() != nullptr;
if (isa<ObjCImplDecl>(ContD))
return true;
return false;
@@ -164,8 +163,7 @@ public:
if (!D)
return false;
- for (Decl::redecl_iterator
- I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I)
+ for (auto I : D->redecls())
if (!isInMainFile(I->getLocation()))
return false;
diff --git a/lib/ARCMigrate/TransGCCalls.cpp b/lib/ARCMigrate/TransGCCalls.cpp
index 249f20f01b22..3a236d34cd4b 100644
--- a/lib/ARCMigrate/TransGCCalls.cpp
+++ b/lib/ARCMigrate/TransGCCalls.cpp
@@ -38,14 +38,8 @@ public:
TransformActions &TA = MigrateCtx.Pass.TA;
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
- if (MigrateCtx.Pass.noNSAllocReallocError())
- TA.reportWarning("call returns pointer to GC managed memory; "
- "it will become unmanaged in ARC",
- E->getLocStart(), E->getSourceRange());
- else
- TA.reportError("call returns pointer to GC managed memory; "
- "it will become unmanaged in ARC",
- E->getLocStart(), E->getSourceRange());
+ TA.report(E->getLocStart(), diag::warn_arcmt_nsalloc_realloc,
+ E->getSourceRange());
return true;
}
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index b6ddc43dd69f..ab128844b45f 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -61,7 +61,8 @@ class PropertiesRewriter {
ObjCIvarDecl *IvarD;
ObjCPropertyImplDecl *ImplD;
- PropData(ObjCPropertyDecl *propD) : PropD(propD), IvarD(0), ImplD(0) { }
+ PropData(ObjCPropertyDecl *propD)
+ : PropD(propD), IvarD(nullptr), ImplD(nullptr) {}
};
typedef SmallVector<PropData, 2> PropsTy;
@@ -74,18 +75,16 @@ public:
: MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { }
static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps,
- AtPropDeclsTy *PrevAtProps = 0) {
- for (ObjCInterfaceDecl::prop_iterator
- propI = D->prop_begin(),
- propE = D->prop_end(); propI != propE; ++propI) {
- if (propI->getAtLoc().isInvalid())
+ AtPropDeclsTy *PrevAtProps = nullptr) {
+ for (auto *Prop : D->properties()) {
+ if (Prop->getAtLoc().isInvalid())
continue;
- unsigned RawLoc = propI->getAtLoc().getRawEncoding();
+ unsigned RawLoc = Prop->getAtLoc().getRawEncoding();
if (PrevAtProps)
if (PrevAtProps->find(RawLoc) != PrevAtProps->end())
continue;
PropsTy &props = AtProps[RawLoc];
- props.push_back(*propI);
+ props.push_back(Prop);
}
}
@@ -141,12 +140,8 @@ public:
AtPropDeclsTy AtExtProps;
// Look through extensions.
- for (ObjCInterfaceDecl::visible_extensions_iterator
- ext = iface->visible_extensions_begin(),
- extEnd = iface->visible_extensions_end();
- ext != extEnd; ++ext) {
- collectProperties(*ext, AtExtProps, &AtProps);
- }
+ for (auto *Ext : iface->visible_extensions())
+ collectProperties(Ext, AtExtProps, &AtProps);
for (AtPropDeclsTy::iterator
I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) {
@@ -353,14 +348,6 @@ private:
return false;
}
- bool hasAllIvarsBacked(PropsTy &props) const {
- for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
- if (!isUserDeclared(I->IvarD))
- return false;
-
- return true;
- }
-
// \brief Returns true if all declarations in the @property have GC __weak.
bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const {
if (!Pass.isGCMigration())
diff --git a/lib/ARCMigrate/TransProtectedScope.cpp b/lib/ARCMigrate/TransProtectedScope.cpp
index 237aa42877e6..0fcbcbedfe04 100644
--- a/lib/ARCMigrate/TransProtectedScope.cpp
+++ b/lib/ARCMigrate/TransProtectedScope.cpp
@@ -47,7 +47,7 @@ struct CaseInfo {
St_Fixed
} State;
- CaseInfo() : SC(0), State(St_Unchecked) {}
+ CaseInfo() : SC(nullptr), State(St_Unchecked) {}
CaseInfo(SwitchCase *S, SourceRange Range)
: SC(S), Range(Range), State(St_Unchecked) {}
};
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index 446a284a286f..bcbc9e9612ba 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -38,13 +38,13 @@ class RetainReleaseDeallocRemover :
MigrationPass &Pass;
ExprSet Removables;
- OwningPtr<ParentMap> StmtMap;
+ std::unique_ptr<ParentMap> StmtMap;
Selector DelegateSel, FinalizeSel;
public:
RetainReleaseDeallocRemover(MigrationPass &pass)
- : Body(0), Pass(pass) {
+ : Body(nullptr), Pass(pass) {
DelegateSel =
Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("delegate"));
FinalizeSel =
@@ -70,7 +70,7 @@ public:
// An unused autorelease is badness. If we remove it the receiver
// will likely die immediately while previously it was kept alive
// by the autorelease pool. This is bad practice in general, leave it
- // and emit an error to force the user to restructure his code.
+ // and emit an error to force the user to restructure their code.
Pass.TA.reportError("it is not safe to remove an unused 'autorelease' "
"message; its receiver may be destroyed immediately",
E->getLocStart(), E->getSourceRange());
@@ -212,7 +212,7 @@ private:
return false;
Stmt *prevStmt, *nextStmt;
- llvm::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E);
+ std::tie(prevStmt, nextStmt) = getPreviousAndNextStmt(E);
return isPlusOneAssignToVar(prevStmt, RefD) ||
isPlusOneAssignToVar(nextStmt, RefD);
@@ -248,7 +248,7 @@ private:
}
std::pair<Stmt *, Stmt *> getPreviousAndNextStmt(Expr *E) {
- Stmt *prevStmt = 0, *nextStmt = 0;
+ Stmt *prevStmt = nullptr, *nextStmt = nullptr;
if (!E)
return std::make_pair(prevStmt, nextStmt);
@@ -294,7 +294,7 @@ private:
Decl *getReferencedDecl(Expr *E) {
if (!E)
- return 0;
+ return nullptr;
E = E->IgnoreParenCasts();
if (ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) {
@@ -305,7 +305,7 @@ private:
case OMF_retain:
return getReferencedDecl(ME->getInstanceReceiver());
default:
- return 0;
+ return nullptr;
}
}
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
@@ -315,7 +315,7 @@ private:
if (ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(E))
return IRE->getDecl();
- return 0;
+ return nullptr;
}
/// \brief Check if the retain/release is due to a GCD/XPC macro that are
@@ -345,7 +345,7 @@ private:
if (!isGCDOrXPC)
return;
- StmtExpr *StmtE = 0;
+ StmtExpr *StmtE = nullptr;
Stmt *S = Msg;
while (S) {
if (StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
diff --git a/lib/ARCMigrate/TransUnbridgedCasts.cpp b/lib/ARCMigrate/TransUnbridgedCasts.cpp
index 7b360c640cfd..7ca49558a7f0 100644
--- a/lib/ARCMigrate/TransUnbridgedCasts.cpp
+++ b/lib/ARCMigrate/TransUnbridgedCasts.cpp
@@ -60,13 +60,14 @@ namespace {
class UnbridgedCastRewriter : public RecursiveASTVisitor<UnbridgedCastRewriter>{
MigrationPass &Pass;
IdentifierInfo *SelfII;
- OwningPtr<ParentMap> StmtMap;
+ std::unique_ptr<ParentMap> StmtMap;
Decl *ParentD;
Stmt *Body;
- mutable OwningPtr<ExprSet> Removables;
+ mutable std::unique_ptr<ExprSet> Removables;
public:
- UnbridgedCastRewriter(MigrationPass &pass) : Pass(pass), ParentD(0), Body(0) {
+ UnbridgedCastRewriter(MigrationPass &pass)
+ : Pass(pass), ParentD(nullptr), Body(nullptr) {
SelfII = &Pass.Ctx.Idents.get("self");
}
@@ -133,11 +134,11 @@ private:
Expr *inner = E->IgnoreParenCasts();
if (CallExpr *callE = dyn_cast<CallExpr>(inner)) {
if (FunctionDecl *FD = callE->getDirectCallee()) {
- if (FD->getAttr<CFReturnsRetainedAttr>()) {
+ if (FD->hasAttr<CFReturnsRetainedAttr>()) {
castToObjCObject(E, /*retained=*/true);
return;
}
- if (FD->getAttr<CFReturnsNotRetainedAttr>()) {
+ if (FD->hasAttr<CFReturnsNotRetainedAttr>()) {
castToObjCObject(E, /*retained=*/false);
return;
}
@@ -283,7 +284,7 @@ private:
SourceLocation Loc = E->getExprLoc();
assert(Loc.isMacroID());
SourceLocation MacroBegin, MacroEnd;
- llvm::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
+ std::tie(MacroBegin, MacroEnd) = SM.getImmediateExpansionRange(Loc);
SourceRange SubRange = E->getSubExpr()->IgnoreParenImpCasts()->getSourceRange();
SourceLocation InnerBegin = SM.getImmediateMacroCallerLoc(SubRange.getBegin());
SourceLocation InnerEnd = SM.getImmediateMacroCallerLoc(SubRange.getEnd());
@@ -439,7 +440,7 @@ private:
}
if (i < callE->getNumArgs() && i < FD->getNumParams()) {
ParmVarDecl *PD = FD->getParamDecl(i);
- if (PD->getAttr<CFConsumedAttr>()) {
+ if (PD->hasAttr<CFConsumedAttr>()) {
isConsumed = true;
return true;
}
diff --git a/lib/ARCMigrate/TransUnusedInitDelegate.cpp b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
index e316c73fc3cd..98571c035dd5 100644
--- a/lib/ARCMigrate/TransUnusedInitDelegate.cpp
+++ b/lib/ARCMigrate/TransUnusedInitDelegate.cpp
@@ -39,7 +39,7 @@ class UnusedInitRewriter : public RecursiveASTVisitor<UnusedInitRewriter> {
public:
UnusedInitRewriter(MigrationPass &pass)
- : Body(0), Pass(pass) { }
+ : Body(nullptr), Pass(pass) { }
void transformBody(Stmt *body, Decl *ParentD) {
Body = body;
diff --git a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
index 4d088e05bfab..76ce0ec90db3 100644
--- a/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
+++ b/lib/ARCMigrate/TransZeroOutPropsInDealloc.cpp
@@ -35,7 +35,7 @@ class ZeroOutInDeallocRemover :
Selector FinalizeSel;
public:
- ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(0) {
+ ZeroOutInDeallocRemover(MigrationPass &pass) : Pass(pass), SelfD(nullptr) {
FinalizeSel =
Pass.Ctx.Selectors.getNullarySelector(&Pass.Ctx.Idents.get("finalize"));
}
@@ -113,23 +113,21 @@ public:
// For a 'dealloc' method use, find all property implementations in
// this class implementation.
- for (ObjCImplDecl::propimpl_iterator
- I = IMD->propimpl_begin(), EI = IMD->propimpl_end(); I != EI; ++I) {
- ObjCPropertyImplDecl *PID = *I;
- if (PID->getPropertyImplementation() ==
- ObjCPropertyImplDecl::Synthesize) {
- ObjCPropertyDecl *PD = PID->getPropertyDecl();
- ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
- if (!(setterM && setterM->isDefined())) {
- ObjCPropertyDecl::PropertyAttributeKind AttrKind =
- PD->getPropertyAttributes();
- if (AttrKind &
- (ObjCPropertyDecl::OBJC_PR_retain |
- ObjCPropertyDecl::OBJC_PR_copy |
- ObjCPropertyDecl::OBJC_PR_strong))
- SynthesizedProperties[PD] = PID;
- }
+ for (auto *PID : IMD->property_impls()) {
+ if (PID->getPropertyImplementation() ==
+ ObjCPropertyImplDecl::Synthesize) {
+ ObjCPropertyDecl *PD = PID->getPropertyDecl();
+ ObjCMethodDecl *setterM = PD->getSetterMethodDecl();
+ if (!(setterM && setterM->isDefined())) {
+ ObjCPropertyDecl::PropertyAttributeKind AttrKind =
+ PD->getPropertyAttributes();
+ if (AttrKind &
+ (ObjCPropertyDecl::OBJC_PR_retain |
+ ObjCPropertyDecl::OBJC_PR_copy |
+ ObjCPropertyDecl::OBJC_PR_strong))
+ SynthesizedProperties[PD] = PID;
}
+ }
}
// Now, remove all zeroing of ivars etc.
@@ -137,7 +135,7 @@ public:
// clear out for next method.
SynthesizedProperties.clear();
- SelfD = 0;
+ SelfD = nullptr;
Removables.clear();
return true;
}
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index 2fd0619df9f8..6d178bea0907 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -601,7 +601,7 @@ TransformActions::RewriteReceiver::~RewriteReceiver() { }
TransformActions::TransformActions(DiagnosticsEngine &diag,
CapturedDiagList &capturedDiags,
ASTContext &ctx, Preprocessor &PP)
- : Diags(diag), CapturedDiags(capturedDiags), ReportedErrors(false) {
+ : Diags(diag), CapturedDiags(capturedDiags) {
Impl = new TransformActionsImpl(capturedDiags, ctx, PP);
}
@@ -673,60 +673,24 @@ void TransformActions::applyRewrites(RewriteReceiver &receiver) {
static_cast<TransformActionsImpl*>(Impl)->applyRewrites(receiver);
}
-void TransformActions::reportError(StringRef error, SourceLocation loc,
- SourceRange range) {
- assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
+DiagnosticBuilder TransformActions::report(SourceLocation loc, unsigned diagId,
+ SourceRange range) {
+ assert(!static_cast<TransformActionsImpl *>(Impl)->isInTransaction() &&
"Errors should be emitted out of a transaction");
-
- SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
- getASTContext().getSourceManager();
- if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
- return;
-
- // FIXME: Use a custom category name to distinguish rewriter errors.
- std::string rewriteErr = "[rewriter] ";
- rewriteErr += error;
- unsigned diagID
- = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Error,
- rewriteErr);
- Diags.Report(loc, diagID) << range;
- ReportedErrors = true;
+ return Diags.Report(loc, diagId) << range;
}
-void TransformActions::reportWarning(StringRef warning, SourceLocation loc,
+void TransformActions::reportError(StringRef message, SourceLocation loc,
SourceRange range) {
- assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
- "Warning should be emitted out of a transaction");
-
- SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
- getASTContext().getSourceManager();
- if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
- return;
-
- // FIXME: Use a custom category name to distinguish rewriter errors.
- std::string rewriterWarn = "[rewriter] ";
- rewriterWarn += warning;
- unsigned diagID
- = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning,
- rewriterWarn);
- Diags.Report(loc, diagID) << range;
+ report(loc, diag::err_mt_message, range) << message;
}
-void TransformActions::reportNote(StringRef note, SourceLocation loc,
- SourceRange range) {
- assert(!static_cast<TransformActionsImpl*>(Impl)->isInTransaction() &&
- "Errors should be emitted out of a transaction");
-
- SourceManager &SM = static_cast<TransformActionsImpl*>(Impl)->
- getASTContext().getSourceManager();
- if (SM.isInSystemHeader(SM.getExpansionLoc(loc)))
- return;
+void TransformActions::reportWarning(StringRef message, SourceLocation loc,
+ SourceRange range) {
+ report(loc, diag::warn_mt_message, range) << message;
+}
- // FIXME: Use a custom category name to distinguish rewriter errors.
- std::string rewriteNote = "[rewriter] ";
- rewriteNote += note;
- unsigned diagID
- = Diags.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Note,
- rewriteNote);
- Diags.Report(loc, diagID) << range;
+void TransformActions::reportNote(StringRef message, SourceLocation loc,
+ SourceRange range) {
+ report(loc, diag::note_mt_message, range) << message;
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 679b924ba009..6ff7b6b9db87 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -88,7 +88,7 @@ bool trans::isPlusOne(const Expr *E) {
if (const CallExpr *
callE = dyn_cast<CallExpr>(E->IgnoreParenCasts())) {
if (const FunctionDecl *FD = callE->getDirectCallee()) {
- if (FD->getAttr<CFReturnsRetainedAttr>())
+ if (FD->hasAttr<CFReturnsRetainedAttr>())
return true;
if (FD->isGlobal() &&
@@ -264,9 +264,8 @@ public:
}
bool VisitCompoundStmt(CompoundStmt *S) {
- for (CompoundStmt::body_iterator
- I = S->body_begin(), E = S->body_end(); I != E; ++I)
- mark(*I);
+ for (auto *I : S->body())
+ mark(I);
return true;
}
@@ -414,8 +413,7 @@ bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr,
if (tok.isNot(tok::at)) return false;
lexer.LexFromRawLexer(tok);
if (tok.isNot(tok::raw_identifier)) return false;
- if (StringRef(tok.getRawIdentifierData(), tok.getLength())
- != "property")
+ if (tok.getRawIdentifier() != "property")
return false;
lexer.LexFromRawLexer(tok);
if (tok.isNot(tok::l_paren)) return false;
@@ -431,8 +429,7 @@ bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr,
while (1) {
if (tok.isNot(tok::raw_identifier)) return false;
- StringRef ident(tok.getRawIdentifierData(), tok.getLength());
- if (ident == fromAttr) {
+ if (tok.getRawIdentifier() == fromAttr) {
if (!toAttr.empty()) {
Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr);
return true;
@@ -497,8 +494,7 @@ bool MigrationContext::addPropertyAttribute(StringRef attr,
if (tok.isNot(tok::at)) return false;
lexer.LexFromRawLexer(tok);
if (tok.isNot(tok::raw_identifier)) return false;
- if (StringRef(tok.getRawIdentifierData(), tok.getLength())
- != "property")
+ if (tok.getRawIdentifier() != "property")
return false;
lexer.LexFromRawLexer(tok);
@@ -538,15 +534,12 @@ static void GCRewriteFinalize(MigrationPass &pass) {
impl_iterator;
for (impl_iterator I = impl_iterator(DC->decls_begin()),
E = impl_iterator(DC->decls_end()); I != E; ++I) {
- for (ObjCImplementationDecl::instmeth_iterator
- MI = I->instmeth_begin(),
- ME = I->instmeth_end(); MI != ME; ++MI) {
- ObjCMethodDecl *MD = *MI;
+ for (const auto *MD : I->instance_methods()) {
if (!MD->hasBody())
continue;
if (MD->isInstanceMethod() && MD->getSelector() == FinalizeSel) {
- ObjCMethodDecl *FinalizeM = MD;
+ const ObjCMethodDecl *FinalizeM = MD;
Transaction Trans(TA);
TA.insert(FinalizeM->getSourceRange().getBegin(),
"#if !__has_feature(objc_arc)\n");
diff --git a/lib/ARCMigrate/Transforms.h b/lib/ARCMigrate/Transforms.h
index eab5e85d56b7..12551d261d36 100644
--- a/lib/ARCMigrate/Transforms.h
+++ b/lib/ARCMigrate/Transforms.h
@@ -127,29 +127,29 @@ public:
class PropertyRewriteTraverser : public ASTTraverser {
public:
- virtual void traverseObjCImplementation(ObjCImplementationContext &ImplCtx);
+ void traverseObjCImplementation(ObjCImplementationContext &ImplCtx) override;
};
class BlockObjCVariableTraverser : public ASTTraverser {
public:
- virtual void traverseBody(BodyContext &BodyCtx);
+ void traverseBody(BodyContext &BodyCtx) override;
};
class ProtectedScopeTraverser : public ASTTraverser {
public:
- virtual void traverseBody(BodyContext &BodyCtx);
+ void traverseBody(BodyContext &BodyCtx) override;
};
// GC transformations
class GCAttrsTraverser : public ASTTraverser {
public:
- virtual void traverseTU(MigrationContext &MigrateCtx);
+ void traverseTU(MigrationContext &MigrateCtx) override;
};
class GCCollectableCallsTraverser : public ASTTraverser {
public:
- virtual void traverseBody(BodyContext &BodyCtx);
+ void traverseBody(BodyContext &BodyCtx) override;
};
//===----------------------------------------------------------------------===//
@@ -189,7 +189,7 @@ class BodyTransform : public RecursiveASTVisitor<BodyTransform<BODY_TRANS> > {
typedef RecursiveASTVisitor<BodyTransform<BODY_TRANS> > base;
public:
- BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(0) { }
+ BodyTransform(MigrationPass &pass) : Pass(pass), ParentD(nullptr) { }
bool TraverseStmt(Stmt *rootS) {
if (rootS)
diff --git a/lib/AST/APValue.cpp b/lib/AST/APValue.cpp
index 541836b21b70..0fa0216d9dac 100644
--- a/lib/AST/APValue.cpp
+++ b/lib/AST/APValue.cpp
@@ -34,7 +34,7 @@ namespace {
struct APValue::LV : LVBase {
static const unsigned InlinePathSpace =
- (MaxSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
+ (DataSize - sizeof(LVBase)) / sizeof(LValuePathEntry);
/// Path - The sequence of base classes, fields and array indices to follow to
/// walk from Base to the subobject. When performing GCC-style folding, there
@@ -75,7 +75,7 @@ namespace {
struct APValue::MemberPointerData : MemberPointerBase {
static const unsigned InlinePathSpace =
- (MaxSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
+ (DataSize - sizeof(MemberPointerBase)) / sizeof(const CXXRecordDecl*);
typedef const CXXRecordDecl *PathElem;
union {
PathElem Path[InlinePathSpace];
@@ -117,7 +117,7 @@ APValue::StructData::~StructData() {
delete [] Elts;
}
-APValue::UnionData::UnionData() : Field(0), Value(new APValue) {}
+APValue::UnionData::UnionData() : Field(nullptr), Value(new APValue) {}
APValue::UnionData::~UnionData () {
delete Value;
}
@@ -136,7 +136,7 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
break;
case Vector:
MakeVector();
- setVector(((const Vec *)(const char *)RHS.Data)->Elts,
+ setVector(((const Vec *)(const char *)RHS.Data.buffer)->Elts,
RHS.getVectorLength());
break;
case ComplexInt:
@@ -188,27 +188,27 @@ APValue::APValue(const APValue &RHS) : Kind(Uninitialized) {
void APValue::DestroyDataAndMakeUninit() {
if (Kind == Int)
- ((APSInt*)(char*)Data)->~APSInt();
+ ((APSInt*)(char*)Data.buffer)->~APSInt();
else if (Kind == Float)
- ((APFloat*)(char*)Data)->~APFloat();
+ ((APFloat*)(char*)Data.buffer)->~APFloat();
else if (Kind == Vector)
- ((Vec*)(char*)Data)->~Vec();
+ ((Vec*)(char*)Data.buffer)->~Vec();
else if (Kind == ComplexInt)
- ((ComplexAPSInt*)(char*)Data)->~ComplexAPSInt();
+ ((ComplexAPSInt*)(char*)Data.buffer)->~ComplexAPSInt();
else if (Kind == ComplexFloat)
- ((ComplexAPFloat*)(char*)Data)->~ComplexAPFloat();
+ ((ComplexAPFloat*)(char*)Data.buffer)->~ComplexAPFloat();
else if (Kind == LValue)
- ((LV*)(char*)Data)->~LV();
+ ((LV*)(char*)Data.buffer)->~LV();
else if (Kind == Array)
- ((Arr*)(char*)Data)->~Arr();
+ ((Arr*)(char*)Data.buffer)->~Arr();
else if (Kind == Struct)
- ((StructData*)(char*)Data)->~StructData();
+ ((StructData*)(char*)Data.buffer)->~StructData();
else if (Kind == Union)
- ((UnionData*)(char*)Data)->~UnionData();
+ ((UnionData*)(char*)Data.buffer)->~UnionData();
else if (Kind == MemberPointer)
- ((MemberPointerData*)(char*)Data)->~MemberPointerData();
+ ((MemberPointerData*)(char*)Data.buffer)->~MemberPointerData();
else if (Kind == AddrLabelDiff)
- ((AddrLabelDiffData*)(char*)Data)->~AddrLabelDiffData();
+ ((AddrLabelDiffData*)(char*)Data.buffer)->~AddrLabelDiffData();
Kind = Uninitialized;
}
@@ -239,19 +239,20 @@ bool APValue::needsCleanup() const {
"same size.");
return getComplexIntReal().needsCleanup();
case LValue:
- return reinterpret_cast<const LV *>(Data)->hasPathPtr();
+ return reinterpret_cast<const LV *>(Data.buffer)->hasPathPtr();
case MemberPointer:
- return reinterpret_cast<const MemberPointerData *>(Data)->hasPathPtr();
+ return reinterpret_cast<const MemberPointerData *>(Data.buffer)
+ ->hasPathPtr();
}
llvm_unreachable("Unknown APValue kind!");
}
void APValue::swap(APValue &RHS) {
std::swap(Kind, RHS.Kind);
- char TmpData[MaxSize];
- memcpy(TmpData, Data, MaxSize);
- memcpy(Data, RHS.Data, MaxSize);
- memcpy(RHS.Data, TmpData, MaxSize);
+ char TmpData[DataSize];
+ memcpy(TmpData, Data.buffer, DataSize);
+ memcpy(Data.buffer, RHS.Data.buffer, DataSize);
+ memcpy(RHS.Data.buffer, TmpData, DataSize);
}
void APValue::dump() const {
@@ -402,8 +403,13 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
Out << *VD;
- else
- Base.get<const Expr*>()->printPretty(Out, 0, Ctx.getPrintingPolicy());
+ else {
+ assert(Base.get<const Expr *>() != nullptr &&
+ "Expecting non-null Expr");
+ Base.get<const Expr*>()->printPretty(Out, nullptr,
+ Ctx.getPrintingPolicy());
+ }
+
if (!O.isZero()) {
Out << " + " << (O / S);
if (IsReference)
@@ -424,12 +430,13 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
ElemTy = VD->getType();
} else {
const Expr *E = Base.get<const Expr*>();
- E->printPretty(Out, 0, Ctx.getPrintingPolicy());
+ assert(E != nullptr && "Expecting non-null Expr");
+ E->printPretty(Out, nullptr, Ctx.getPrintingPolicy());
ElemTy = E->getType();
}
ArrayRef<LValuePathEntry> Path = getLValuePath();
- const CXXRecordDecl *CastToBase = 0;
+ const CXXRecordDecl *CastToBase = nullptr;
for (unsigned I = 0, N = Path.size(); I != N; ++I) {
if (ElemTy->getAs<RecordType>()) {
// The lvalue refers to a class type, so the next path entry is a base
@@ -498,8 +505,7 @@ void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
First = false;
}
}
- for (RecordDecl::field_iterator FI = RD->field_begin();
- FI != RD->field_end(); ++FI) {
+ for (const auto *FI : RD->fields()) {
if (!First)
Out << ", ";
if (FI->isUnnamedBitfield()) continue;
@@ -546,39 +552,39 @@ std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
const APValue::LValueBase APValue::getLValueBase() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getPointer();
+ return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getPointer();
}
bool APValue::isLValueOnePastTheEnd() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const void*)Data)->BaseAndIsOnePastTheEnd.getInt();
+ return ((const LV*)(const void*)Data.buffer)->BaseAndIsOnePastTheEnd.getInt();
}
CharUnits &APValue::getLValueOffset() {
assert(isLValue() && "Invalid accessor");
- return ((LV*)(void*)Data)->Offset;
+ return ((LV*)(void*)Data.buffer)->Offset;
}
bool APValue::hasLValuePath() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data)->hasPath();
+ return ((const LV*)(const char*)Data.buffer)->hasPath();
}
ArrayRef<APValue::LValuePathEntry> APValue::getLValuePath() const {
assert(isLValue() && hasLValuePath() && "Invalid accessor");
- const LV &LVal = *((const LV*)(const char*)Data);
+ const LV &LVal = *((const LV*)(const char*)Data.buffer);
return ArrayRef<LValuePathEntry>(LVal.getPath(), LVal.PathLength);
}
unsigned APValue::getLValueCallIndex() const {
assert(isLValue() && "Invalid accessor");
- return ((const LV*)(const char*)Data)->CallIndex;
+ return ((const LV*)(const char*)Data.buffer)->CallIndex;
}
void APValue::setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data);
+ LV &LVal = *((LV*)(char*)Data.buffer);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(false);
LVal.Offset = O;
@@ -590,7 +596,7 @@ void APValue::setLValue(LValueBase B, const CharUnits &O,
ArrayRef<LValuePathEntry> Path, bool IsOnePastTheEnd,
unsigned CallIndex) {
assert(isLValue() && "Invalid accessor");
- LV &LVal = *((LV*)(char*)Data);
+ LV &LVal = *((LV*)(char*)Data.buffer);
LVal.BaseAndIsOnePastTheEnd.setPointer(B);
LVal.BaseAndIsOnePastTheEnd.setInt(IsOnePastTheEnd);
LVal.Offset = O;
@@ -601,39 +607,42 @@ void APValue::setLValue(LValueBase B, const CharUnits &O,
const ValueDecl *APValue::getMemberPointerDecl() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return MPD.MemberAndIsDerivedMember.getPointer();
}
bool APValue::isMemberPointerToDerivedMember() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return MPD.MemberAndIsDerivedMember.getInt();
}
ArrayRef<const CXXRecordDecl*> APValue::getMemberPointerPath() const {
assert(isMemberPointer() && "Invalid accessor");
- const MemberPointerData &MPD = *((const MemberPointerData*)(const char*)Data);
+ const MemberPointerData &MPD =
+ *((const MemberPointerData *)(const char *)Data.buffer);
return ArrayRef<const CXXRecordDecl*>(MPD.getPath(), MPD.PathLength);
}
void APValue::MakeLValue() {
assert(isUninit() && "Bad state change");
- assert(sizeof(LV) <= MaxSize && "LV too big");
- new ((void*)(char*)Data) LV();
+ 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");
- new ((void*)(char*)Data) Arr(InitElts, Size);
+ 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");
- MemberPointerData *MPD = new ((void*)(char*)Data) MemberPointerData;
+ MemberPointerData *MPD = new ((void*)(char*)Data.buffer) MemberPointerData;
Kind = MemberPointer;
MPD->MemberAndIsDerivedMember.setPointer(Member);
MPD->MemberAndIsDerivedMember.setInt(IsDerivedMember);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index a03cf9e7d47b..bccdae91d2eb 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -29,6 +29,7 @@
#include "clang/AST/RecordLayout.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
+#include "clang/AST/VTableBuilder.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -62,6 +63,13 @@ enum FloatingRank {
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;
}
@@ -69,23 +77,23 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// User can not attach documentation to implicit declarations.
if (D->isImplicit())
- return NULL;
+ return nullptr;
// User can not attach documentation to implicit instantiations.
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (VD->isStaticDataMember() &&
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(D)) {
if (CRD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const ClassTemplateSpecializationDecl *CTSD =
@@ -93,35 +101,35 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
TemplateSpecializationKind TSK = CTSD->getSpecializationKind();
if (TSK == TSK_ImplicitInstantiation ||
TSK == TSK_Undeclared)
- return NULL;
+ return nullptr;
}
if (const EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
if (ED->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
- return NULL;
+ return nullptr;
}
if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
// When tag declaration (but not definition!) is part of the
// decl-specifier-seq of some other declaration, it doesn't get comment
if (TD->isEmbeddedInDeclarator() && !TD->isCompleteDefinition())
- return NULL;
+ return nullptr;
}
// TODO: handle comments for function parameters properly.
if (isa<ParmVarDecl>(D))
- return NULL;
+ return nullptr;
// TODO: we could look up template parameter documentation in the template
// documentation.
if (isa<TemplateTypeParmDecl>(D) ||
isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTemplateParmDecl>(D))
- return NULL;
+ return nullptr;
ArrayRef<RawComment *> RawComments = Comments.getComments();
// If there are no comments anywhere, we won't find anything.
if (RawComments.empty())
- return NULL;
+ return nullptr;
// Find declaration location.
// For Objective-C declarations we generally don't expect to have multiple
@@ -137,17 +145,29 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
DeclLoc = D->getLocStart();
else {
DeclLoc = D->getLocation();
- // If location of the typedef name is in a macro, it is because being
- // declared via a macro. Try using declaration's starting location
- // as the "declaration location".
- if (DeclLoc.isMacroID() && isa<TypedefDecl>(D))
- DeclLoc = D->getLocStart();
+ if (DeclLoc.isMacroID()) {
+ if (isa<TypedefDecl>(D)) {
+ // If location of the typedef name is in a macro, it is because being
+ // declared via a macro. Try using declaration's starting location as
+ // the "declaration location".
+ DeclLoc = D->getLocStart();
+ } else if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ // If location of the tag decl is inside a macro, but the spelling of
+ // the tag name comes from a macro argument, it looks like a special
+ // macro like NS_ENUM is being used to define the tag decl. In that
+ // case, adjust the source location to the expansion loc so that we can
+ // attach the comment to the tag decl.
+ if (SourceMgr.isMacroArgExpansion(DeclLoc) &&
+ TD->isCompleteDefinition())
+ DeclLoc = SourceMgr.getExpansionLoc(DeclLoc);
+ }
+ }
}
// If the declaration doesn't map directly to a location in a file, we
// can't find the comment.
if (DeclLoc.isInvalid() || !DeclLoc.isFileID())
- return NULL;
+ return nullptr;
// Find the comment that occurs just after this declaration.
ArrayRef<RawComment *>::iterator Comment;
@@ -201,12 +221,12 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// The comment just after the declaration was not a trailing comment.
// Let's look at the previous comment.
if (Comment == RawComments.begin())
- return NULL;
+ return nullptr;
--Comment;
// Check that we actually have a non-member Doxygen comment.
if (!(*Comment)->isDocumentation() || (*Comment)->isTrailingComment())
- return NULL;
+ return nullptr;
// Decompose the end of the comment.
std::pair<FileID, unsigned> CommentEndDecomp
@@ -215,14 +235,14 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// If the comment and the declaration aren't in the same file, then they
// aren't related.
if (DeclLocDecomp.first != CommentEndDecomp.first)
- return NULL;
+ return nullptr;
// Get the corresponding buffer.
bool Invalid = false;
const char *Buffer = SourceMgr.getBufferData(DeclLocDecomp.first,
&Invalid).data();
if (Invalid)
- return NULL;
+ return nullptr;
// Extract text between the comment and declaration.
StringRef Text(Buffer + CommentEndDecomp.second,
@@ -231,7 +251,7 @@ RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
// There should be no other declarations or preprocessor directives between
// comment and declaration.
if (Text.find_first_of(";{}#@") != StringRef::npos)
- return NULL;
+ return nullptr;
return *Comment;
}
@@ -329,13 +349,11 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
}
// Search for comments attached to declarations in the redeclaration chain.
- const RawComment *RC = NULL;
- const Decl *OriginalDeclForRC = NULL;
- for (Decl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
+ const RawComment *RC = nullptr;
+ const Decl *OriginalDeclForRC = nullptr;
+ for (auto I : D->redecls()) {
llvm::DenseMap<const Decl *, RawCommentAndCacheFlags>::iterator Pos =
- RedeclComments.find(*I);
+ RedeclComments.find(I);
if (Pos != RedeclComments.end()) {
const RawCommentAndCacheFlags &Raw = Pos->second;
if (Raw.getKind() != RawCommentAndCacheFlags::NoCommentInDecl) {
@@ -344,16 +362,16 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
break;
}
} else {
- RC = getRawCommentForDeclNoCache(*I);
- OriginalDeclForRC = *I;
+ RC = getRawCommentForDeclNoCache(I);
+ OriginalDeclForRC = I;
RawCommentAndCacheFlags Raw;
if (RC) {
Raw.setRaw(RC);
Raw.setKind(RawCommentAndCacheFlags::FromDecl);
} else
Raw.setKind(RawCommentAndCacheFlags::NoCommentInDecl);
- Raw.setOriginalDecl(*I);
- RedeclComments[*I] = Raw;
+ Raw.setOriginalDecl(I);
+ RedeclComments[I] = Raw;
if (RC)
break;
}
@@ -371,10 +389,8 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
Raw.setKind(RawCommentAndCacheFlags::FromRedecl);
Raw.setOriginalDecl(OriginalDeclForRC);
- for (Decl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
- RawCommentAndCacheFlags &R = RedeclComments[*I];
+ for (auto I : D->redecls()) {
+ RawCommentAndCacheFlags &R = RedeclComments[I];
if (R.getKind() == RawCommentAndCacheFlags::NoCommentInDecl)
R = Raw;
}
@@ -390,10 +406,7 @@ static void addRedeclaredMethods(const ObjCMethodDecl *ObjCMethod,
if (!ID)
return;
// Add redeclared method here.
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = ID->known_extensions_begin(),
- ExtEnd = ID->known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : ID->known_extensions()) {
if (ObjCMethodDecl *RedeclaredMethod =
Ext->getMethod(ObjCMethod->getSelector(),
ObjCMethod->isInstanceMethod()))
@@ -409,6 +422,8 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
ThisDeclInfo->IsFilled = false;
ThisDeclInfo->fill();
ThisDeclInfo->CommentDecl = FC->getDecl();
+ if (!ThisDeclInfo->TemplateParameters)
+ ThisDeclInfo->TemplateParameters = FC->getDeclInfo()->TemplateParameters;
comments::FullComment *CFC =
new (*this) comments::FullComment(FC->getBlocks(),
ThisDeclInfo);
@@ -418,14 +433,14 @@ comments::FullComment *ASTContext::cloneFullComment(comments::FullComment *FC,
comments::FullComment *ASTContext::getLocalCommentForDeclUncached(const Decl *D) const {
const RawComment *RC = getRawCommentForDeclNoCache(D);
- return RC ? RC->parse(*this, 0, D) : 0;
+ return RC ? RC->parse(*this, nullptr, D) : nullptr;
}
comments::FullComment *ASTContext::getCommentForDecl(
const Decl *D,
const Preprocessor *PP) const {
if (D->isInvalidDecl())
- return NULL;
+ return nullptr;
D = adjustDeclToTemplate(D);
const Decl *Canonical = D->getCanonicalDecl();
@@ -482,13 +497,12 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
if (!(RD = RD->getDefinition()))
- return NULL;
+ return nullptr;
// Check non-virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I =
- RD->bases_begin(), E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual() || (I->getAccessSpecifier() != AS_public))
+ for (const auto &I : RD->bases()) {
+ if (I.isVirtual() || (I.getAccessSpecifier() != AS_public))
continue;
- QualType Ty = I->getType();
+ QualType Ty = I.getType();
if (Ty.isNull())
continue;
if (const CXXRecordDecl *NonVirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -500,11 +514,10 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
}
// Check virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I =
- RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) {
- if (I->getAccessSpecifier() != AS_public)
+ for (const auto &I : RD->vbases()) {
+ if (I.getAccessSpecifier() != AS_public)
continue;
- QualType Ty = I->getType();
+ QualType Ty = I.getType();
if (Ty.isNull())
continue;
if (const CXXRecordDecl *VirtualBase = Ty->getAsCXXRecordDecl()) {
@@ -515,7 +528,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
}
}
}
- return NULL;
+ return nullptr;
}
// If the RawComment was attached to other redeclaration of this Decl, we
@@ -576,7 +589,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
// Check if we already have a canonical template template parameter.
llvm::FoldingSetNodeID ID;
CanonicalTemplateTemplateParm::Profile(ID, TTP);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
CanonicalTemplateTemplateParm *Canonical
= CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
if (Canonical)
@@ -595,7 +608,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
TTP->getDepth(),
- TTP->getIndex(), 0, false,
+ TTP->getIndex(), nullptr, false,
TTP->isParameterPack()));
else if (NonTypeTemplateParmDecl *NTTP
= dyn_cast<NonTypeTemplateParmDecl>(*P)) {
@@ -615,7 +628,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
NTTP->getDepth(),
- NTTP->getPosition(), 0,
+ NTTP->getPosition(), nullptr,
T,
TInfo,
ExpandedTypes.data(),
@@ -626,7 +639,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(),
SourceLocation(),
NTTP->getDepth(),
- NTTP->getPosition(), 0,
+ NTTP->getPosition(), nullptr,
T,
NTTP->isParameterPack(),
TInfo);
@@ -643,7 +656,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
SourceLocation(), TTP->getDepth(),
TTP->getPosition(),
TTP->isParameterPack(),
- 0,
+ nullptr,
TemplateParameterList::Create(*this, SourceLocation(),
SourceLocation(),
CanonParams.data(),
@@ -652,7 +665,7 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
// Get the new insert position for the node we care about.
Canonical = CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos);
- assert(Canonical == 0 && "Shouldn't be in the map!");
+ assert(!Canonical && "Shouldn't be in the map!");
(void)Canonical;
// Create the canonical template template parameter entry.
@@ -662,13 +675,13 @@ ASTContext::getCanonicalTemplateTemplateParmDecl(
}
CXXABI *ASTContext::createCXXABI(const TargetInfo &T) {
- if (!LangOpts.CPlusPlus) return 0;
+ if (!LangOpts.CPlusPlus) return nullptr;
switch (T.getCXXABI().getKind()) {
- case TargetCXXABI::GenericARM:
+ case TargetCXXABI::GenericARM: // Same as Itanium at this level
case TargetCXXABI::iOS:
- return CreateARMCXXABI(*this);
- case TargetCXXABI::GenericAArch64: // Same as Itanium at this level
+ case TargetCXXABI::iOS64:
+ case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
return CreateItaniumCXXABI(*this);
case TargetCXXABI::Microsoft:
@@ -710,47 +723,40 @@ static bool isAddrSpaceMapManglingEnabled(const TargetInfo &TI,
}
ASTContext::ASTContext(LangOptions& LOpts, SourceManager &SM,
- const TargetInfo *t,
IdentifierTable &idents, SelectorTable &sels,
- Builtin::Context &builtins,
- unsigned size_reserve,
- bool DelayInitialization)
+ Builtin::Context &builtins)
: FunctionProtoTypes(this_()),
TemplateSpecializationTypes(this_()),
DependentTemplateSpecializationTypes(this_()),
SubstTemplateTemplateParmPacks(this_()),
- GlobalNestedNameSpecifier(0),
- Int128Decl(0), UInt128Decl(0), Float128StubDecl(0),
- BuiltinVaListDecl(0),
- ObjCIdDecl(0), ObjCSelDecl(0), ObjCClassDecl(0), ObjCProtocolClassDecl(0),
- BOOLDecl(0),
- CFConstantStringTypeDecl(0), ObjCInstanceTypeDecl(0),
- FILEDecl(0),
- jmp_bufDecl(0), sigjmp_bufDecl(0), ucontext_tDecl(0),
- BlockDescriptorType(0), BlockDescriptorExtendedType(0),
- cudaConfigureCallDecl(0),
+ GlobalNestedNameSpecifier(nullptr),
+ Int128Decl(nullptr), UInt128Decl(nullptr), Float128StubDecl(nullptr),
+ BuiltinVaListDecl(nullptr),
+ ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
+ ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
+ CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr),
+ FILEDecl(nullptr),
+ jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
+ BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr),
+ cudaConfigureCallDecl(nullptr),
NullTypeSourceInfo(QualType()),
FirstLocalImport(), LastLocalImport(),
SourceMgr(SM), LangOpts(LOpts),
- AddrSpaceMap(0), Target(t), PrintingPolicy(LOpts),
+ AddrSpaceMap(nullptr), Target(nullptr), PrintingPolicy(LOpts),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins),
DeclarationNames(*this),
- ExternalSource(0), Listener(0),
+ ExternalSource(nullptr), Listener(nullptr),
Comments(SM), CommentsLoaded(false),
CommentCommandTraits(BumpAlloc, LOpts.CommentOpts),
- LastSDM(0, 0)
+ LastSDM(nullptr, 0)
{
- if (size_reserve > 0) Types.reserve(size_reserve);
TUDecl = TranslationUnitDecl::Create(*this);
-
- if (!DelayInitialization) {
- assert(t && "No target supplied for ASTContext initialization");
- InitBuiltinTypes(*t);
- }
}
ASTContext::~ASTContext() {
+ ReleaseParentMapEntries();
+
// Release the DenseMaps associated with DeclContext objects.
// FIXME: Is this the ideal solution?
ReleaseDeclContextMaps();
@@ -782,11 +788,19 @@ ASTContext::~ASTContext() {
A != AEnd; ++A)
A->second->~AttrVec();
- for (llvm::DenseMap<const DeclContext *, MangleNumberingContext *>::iterator
- I = MangleNumberingContexts.begin(),
- E = MangleNumberingContexts.end();
- I != E; ++I)
- delete I->second;
+ llvm::DeleteContainerSeconds(MangleNumberingContexts);
+}
+
+void ASTContext::ReleaseParentMapEntries() {
+ if (!AllParents) return;
+ for (const auto &Entry : *AllParents) {
+ if (Entry.second.is<ast_type_traits::DynTypedNode *>()) {
+ delete Entry.second.get<ast_type_traits::DynTypedNode *>();
+ } else {
+ assert(Entry.second.is<ParentVector *>());
+ delete Entry.second.get<ParentVector *>();
+ }
+ }
}
void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
@@ -794,8 +808,8 @@ void ASTContext::AddDeallocation(void (*Callback)(void*), void *Data) {
}
void
-ASTContext::setExternalSource(OwningPtr<ExternalASTSource> &Source) {
- ExternalSource.reset(Source.take());
+ASTContext::setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source) {
+ ExternalSource = Source;
}
void ASTContext::PrintStats() const {
@@ -849,7 +863,7 @@ void ASTContext::PrintStats() const {
<< NumImplicitDestructors
<< " implicit destructors created\n";
- if (ExternalSource.get()) {
+ if (ExternalSource) {
llvm::errs() << "\n";
ExternalSource->PrintStats();
}
@@ -857,45 +871,47 @@ void ASTContext::PrintStats() const {
BumpAlloc.PrintStats();
}
+RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
+ RecordDecl::TagKind TK) const {
+ SourceLocation Loc;
+ RecordDecl *NewDecl;
+ if (getLangOpts().CPlusPlus)
+ NewDecl = CXXRecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc,
+ Loc, &Idents.get(Name));
+ else
+ NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,
+ &Idents.get(Name));
+ NewDecl->setImplicit();
+ return NewDecl;
+}
+
+TypedefDecl *ASTContext::buildImplicitTypedef(QualType T,
+ StringRef Name) const {
+ TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(T);
+ TypedefDecl *NewDecl = TypedefDecl::Create(
+ const_cast<ASTContext &>(*this), getTranslationUnitDecl(),
+ SourceLocation(), SourceLocation(), &Idents.get(Name), TInfo);
+ NewDecl->setImplicit();
+ return NewDecl;
+}
+
TypedefDecl *ASTContext::getInt128Decl() const {
- if (!Int128Decl) {
- TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(Int128Ty);
- Int128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__int128_t"),
- TInfo);
- }
-
+ if (!Int128Decl)
+ Int128Decl = buildImplicitTypedef(Int128Ty, "__int128_t");
return Int128Decl;
}
TypedefDecl *ASTContext::getUInt128Decl() const {
- if (!UInt128Decl) {
- TypeSourceInfo *TInfo = getTrivialTypeSourceInfo(UnsignedInt128Ty);
- UInt128Decl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__uint128_t"),
- TInfo);
- }
-
+ if (!UInt128Decl)
+ UInt128Decl = buildImplicitTypedef(UnsignedInt128Ty, "__uint128_t");
return UInt128Decl;
}
TypeDecl *ASTContext::getFloat128StubType() const {
assert(LangOpts.CPlusPlus && "should only be called for c++");
- if (!Float128StubDecl) {
- Float128StubDecl = CXXRecordDecl::Create(const_cast<ASTContext &>(*this),
- TTK_Struct,
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("__float128"));
- }
-
+ if (!Float128StubDecl)
+ Float128StubDecl = buildImplicitRecord("__float128");
+
return Float128StubDecl;
}
@@ -1106,7 +1122,7 @@ FunctionDecl *ASTContext::getClassScopeSpecializationPattern(
llvm::DenseMap<const FunctionDecl*, FunctionDecl *>::const_iterator Pos
= ClassScopeSpecializationPattern.find(FD);
if (Pos == ClassScopeSpecializationPattern.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1123,7 +1139,7 @@ ASTContext::getInstantiatedFromUsingDecl(UsingDecl *UUD) {
llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
= InstantiatedFromUsingDecl.find(UUD);
if (Pos == InstantiatedFromUsingDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1143,7 +1159,7 @@ ASTContext::getInstantiatedFromUsingShadowDecl(UsingShadowDecl *Inst) {
llvm::DenseMap<UsingShadowDecl*, UsingShadowDecl*>::const_iterator Pos
= InstantiatedFromUsingShadowDecl.find(Inst);
if (Pos == InstantiatedFromUsingShadowDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1159,7 +1175,7 @@ FieldDecl *ASTContext::getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field) {
llvm::DenseMap<FieldDecl *, FieldDecl *>::iterator Pos
= InstantiatedFromUnnamedFieldDecl.find(Field);
if (Pos == InstantiatedFromUnnamedFieldDecl.end())
- return 0;
+ return nullptr;
return Pos->second;
}
@@ -1179,7 +1195,7 @@ ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
= OverriddenMethods.find(Method->getCanonicalDecl());
if (Pos == OverriddenMethods.end())
- return 0;
+ return nullptr;
return Pos->second.begin();
}
@@ -1189,7 +1205,7 @@ ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator Pos
= OverriddenMethods.find(Method->getCanonicalDecl());
if (Pos == OverriddenMethods.end())
- return 0;
+ return nullptr;
return Pos->second.end();
}
@@ -1293,13 +1309,14 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
} else if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
- if (const ReferenceType* RT = T->getAs<ReferenceType>()) {
+ if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
if (ForAlignof)
T = RT->getPointeeType();
else
T = getPointerType(RT->getPointeeType());
}
- if (!T->isIncompleteType() && !T->isFunctionType()) {
+ QualType BaseT = getBaseElementType(T);
+ if (!BaseT->isIncompleteType() && !T->isFunctionType()) {
// Adjust alignments of declarations with array type by the
// large-array alignment on the target.
if (const ArrayType *arrayType = getAsArrayType(T)) {
@@ -1311,9 +1328,6 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
MinWidth <= getTypeSize(cast<ConstantArrayType>(arrayType)))
Align = std::max(Align, Target->getLargeArrayAlign());
}
-
- // Walk through any array types while we're at it.
- T = getBaseElementType(arrayType);
}
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
@@ -1618,7 +1632,7 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::MemberPointer: {
const MemberPointerType *MPT = cast<MemberPointerType>(T);
- llvm::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
+ std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
break;
}
case Type::Complex: {
@@ -1632,8 +1646,9 @@ ASTContext::getTypeInfoImpl(const Type *T) const {
}
case Type::ObjCObject:
return getTypeInfo(cast<ObjCObjectType>(T)->getBaseType().getTypePtr());
+ case Type::Adjusted:
case Type::Decayed:
- return getTypeInfo(cast<DecayedType>(T)->getDecayedType().getTypePtr());
+ return getTypeInfo(cast<AdjustedType>(T)->getAdjustedType().getTypePtr());
case Type::ObjCInterface: {
const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -1761,13 +1776,19 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
if (Target->getTriple().getArch() == llvm::Triple::xcore)
return ABIAlign; // Never overalign on XCore.
+ const TypedefType *TT = T->getAs<TypedefType>();
+
// Double and long long should be naturally aligned if possible.
- if (const ComplexType* CT = T->getAs<ComplexType>())
+ T = T->getBaseElementTypeUnsafe();
+ if (const ComplexType *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
T->isSpecificBuiltinType(BuiltinType::LongLong) ||
T->isSpecificBuiltinType(BuiltinType::ULongLong))
- return std::max(ABIAlign, (unsigned)getTypeSize(T));
+ // Don't increase the alignment if an alignment attribute was specified on a
+ // typedef declaration.
+ if (!TT || !TT->getDecl()->getMaxAlignment())
+ return std::max(ABIAlign, (unsigned)getTypeSize(T));
return ABIAlign;
}
@@ -1796,9 +1817,8 @@ void ASTContext::DeepCollectObjCIvars(const ObjCInterfaceDecl *OI,
if (const ObjCInterfaceDecl *SuperClass = OI->getSuperClass())
DeepCollectObjCIvars(SuperClass, false, Ivars);
if (!leafClass) {
- for (ObjCInterfaceDecl::ivar_iterator I = OI->ivar_begin(),
- E = OI->ivar_end(); I != E; ++I)
- Ivars.push_back(*I);
+ for (const auto *I : OI->ivars())
+ Ivars.push_back(I);
} else {
ObjCInterfaceDecl *IDecl = const_cast<ObjCInterfaceDecl *>(OI);
for (const ObjCIvarDecl *Iv = IDecl->all_declared_ivar_begin(); Iv;
@@ -1814,24 +1834,17 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
if (const ObjCInterfaceDecl *OI = dyn_cast<ObjCInterfaceDecl>(CDecl)) {
// We can use protocol_iterator here instead of
// all_referenced_protocol_iterator since we are walking all categories.
- for (ObjCInterfaceDecl::all_protocol_iterator P = OI->all_referenced_protocol_begin(),
- PE = OI->all_referenced_protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OI->all_referenced_protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P) {
- Protocols.insert((*P)->getCanonicalDecl());
- CollectInheritedProtocols(*P, Protocols);
+ for (auto *P : Proto->protocols()) {
+ Protocols.insert(P->getCanonicalDecl());
+ CollectInheritedProtocols(P, Protocols);
}
}
// Categories of this Interface.
- for (ObjCInterfaceDecl::visible_categories_iterator
- Cat = OI->visible_categories_begin(),
- CatEnd = OI->visible_categories_end();
- Cat != CatEnd; ++Cat) {
- CollectInheritedProtocols(*Cat, Protocols);
- }
+ for (const auto *Cat : OI->visible_categories())
+ CollectInheritedProtocols(Cat, Protocols);
if (ObjCInterfaceDecl *SD = OI->getSuperClass())
while (SD) {
@@ -1839,22 +1852,16 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
SD = SD->getSuperClass();
}
} else if (const ObjCCategoryDecl *OC = dyn_cast<ObjCCategoryDecl>(CDecl)) {
- for (ObjCCategoryDecl::protocol_iterator P = OC->protocol_begin(),
- PE = OC->protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OC->protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P)
- CollectInheritedProtocols(*P, Protocols);
+ for (const auto *P : Proto->protocols())
+ CollectInheritedProtocols(P, Protocols);
}
} else if (const ObjCProtocolDecl *OP = dyn_cast<ObjCProtocolDecl>(CDecl)) {
- for (ObjCProtocolDecl::protocol_iterator P = OP->protocol_begin(),
- PE = OP->protocol_end(); P != PE; ++P) {
- ObjCProtocolDecl *Proto = (*P);
+ for (auto *Proto : OP->protocols()) {
Protocols.insert(Proto->getCanonicalDecl());
- for (ObjCProtocolDecl::protocol_iterator P = Proto->protocol_begin(),
- PE = Proto->protocol_end(); P != PE; ++P)
- CollectInheritedProtocols(*P, Protocols);
+ for (const auto *P : Proto->protocols())
+ CollectInheritedProtocols(P, Protocols);
}
}
}
@@ -1862,12 +1869,8 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
unsigned count = 0;
// Count ivars declared in class extension.
- for (ObjCInterfaceDecl::known_extensions_iterator
- Ext = OI->known_extensions_begin(),
- ExtEnd = OI->known_extensions_end();
- Ext != ExtEnd; ++Ext) {
+ for (const auto *Ext : OI->known_extensions())
count += Ext->ivar_size();
- }
// Count ivar defined in this class's implementation. This
// includes synthesized ivars.
@@ -1901,7 +1904,7 @@ ObjCImplementationDecl *ASTContext::getObjCImplementation(ObjCInterfaceDecl *D)
I = ObjCImpls.find(D);
if (I != ObjCImpls.end())
return cast<ObjCImplementationDecl>(I->second);
- return 0;
+ return nullptr;
}
/// \brief Get the implementation of ObjCCategoryDecl, or NULL if none exists.
ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
@@ -1909,7 +1912,7 @@ ObjCCategoryImplDecl *ASTContext::getObjCImplementation(ObjCCategoryDecl *D) {
I = ObjCImpls.find(D);
if (I != ObjCImpls.end())
return cast<ObjCCategoryImplDecl>(I->second);
- return 0;
+ return nullptr;
}
/// \brief Set the implementation of ObjCInterfaceDecl.
@@ -1937,7 +1940,7 @@ const ObjCInterfaceDecl *ASTContext::getObjContainingInterface(
dyn_cast<ObjCImplDecl>(ND->getDeclContext()))
return IMD->getClassInterface();
- return 0;
+ return nullptr;
}
/// \brief Get the copy initialization expression of VarDecl,or NULL if
@@ -1948,7 +1951,7 @@ Expr *ASTContext::getBlockVarCopyInits(const VarDecl*VD) {
"getBlockVarCopyInits - not __block var");
llvm::DenseMap<const VarDecl*, Expr*>::iterator
I = BlockVarCopyInits.find(VD);
- return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : 0;
+ return (I != BlockVarCopyInits.end()) ? cast<Expr>(I->second) : nullptr;
}
/// \brief Set the copy inialization expression of a block var decl.
@@ -1982,7 +1985,7 @@ TypeSourceInfo *ASTContext::getTrivialTypeSourceInfo(QualType T,
const ASTRecordLayout &
ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const {
- return getObjCLayout(D, 0);
+ return getObjCLayout(D, nullptr);
}
const ASTRecordLayout &
@@ -2003,7 +2006,7 @@ ASTContext::getExtQualType(const Type *baseType, Qualifiers quals) const {
// Check if we've already instantiated this type.
llvm::FoldingSetNodeID ID;
ExtQuals::Profile(ID, baseType, quals);
- void *insertPos = 0;
+ void *insertPos = nullptr;
if (ExtQuals *eq = ExtQualNodes.FindNodeOrInsertPos(ID, insertPos)) {
assert(eq->getQualifiers() == quals);
return QualType(eq, fastQuals);
@@ -2080,12 +2083,12 @@ const FunctionType *ASTContext::adjustFunctionType(const FunctionType *T,
QualType Result;
if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(T)) {
- Result = getFunctionNoProtoType(FNPT->getResultType(), Info);
+ Result = getFunctionNoProtoType(FNPT->getReturnType(), Info);
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(T);
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = Info;
- Result = getFunctionType(FPT->getResultType(), FPT->getArgTypes(), EPI);
+ Result = getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI);
}
return cast<FunctionType>(Result.getTypePtr());
@@ -2097,7 +2100,7 @@ void ASTContext::adjustDeducedFunctionResultType(FunctionDecl *FD,
while (true) {
const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>();
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
- FD->setType(getFunctionType(ResultType, FPT->getArgTypes(), EPI));
+ FD->setType(getFunctionType(ResultType, FPT->getParamTypes(), EPI));
if (FunctionDecl *Next = FD->getPreviousDecl())
FD = Next;
else
@@ -2115,7 +2118,7 @@ QualType ASTContext::getComplexType(QualType T) const {
llvm::FoldingSetNodeID ID;
ComplexType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ComplexType *CT = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(CT, 0);
@@ -2127,7 +2130,7 @@ QualType ASTContext::getComplexType(QualType T) const {
// Get the new insert position for the node we care about.
ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ComplexType *New = new (*this, TypeAlignment) ComplexType(T, Canonical);
Types.push_back(New);
@@ -2143,7 +2146,7 @@ QualType ASTContext::getPointerType(QualType T) const {
llvm::FoldingSetNodeID ID;
PointerType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (PointerType *PT = PointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2155,7 +2158,7 @@ QualType ASTContext::getPointerType(QualType T) const {
// Get the new insert position for the node we care about.
PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
PointerType *New = new (*this, TypeAlignment) PointerType(T, Canonical);
Types.push_back(New);
@@ -2163,15 +2166,30 @@ QualType ASTContext::getPointerType(QualType T) const {
return QualType(New, 0);
}
+QualType ASTContext::getAdjustedType(QualType Orig, QualType New) const {
+ llvm::FoldingSetNodeID ID;
+ AdjustedType::Profile(ID, Orig, New);
+ void *InsertPos = nullptr;
+ AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (AT)
+ return QualType(AT, 0);
+
+ QualType Canonical = getCanonicalType(New);
+
+ // Get the new insert position for the node we care about.
+ AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!AT && "Shouldn't be in the map!");
+
+ AT = new (*this, TypeAlignment)
+ AdjustedType(Type::Adjusted, Orig, New, Canonical);
+ Types.push_back(AT);
+ AdjustedTypes.InsertNode(AT, InsertPos);
+ return QualType(AT, 0);
+}
+
QualType ASTContext::getDecayedType(QualType T) const {
assert((T->isArrayType() || T->isFunctionType()) && "T does not decay");
- llvm::FoldingSetNodeID ID;
- DecayedType::Profile(ID, T);
- void *InsertPos = 0;
- if (DecayedType *DT = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos))
- return QualType(DT, 0);
-
QualType Decayed;
// C99 6.7.5.3p7:
@@ -2189,17 +2207,23 @@ QualType ASTContext::getDecayedType(QualType T) const {
if (T->isFunctionType())
Decayed = getPointerType(T);
+ llvm::FoldingSetNodeID ID;
+ AdjustedType::Profile(ID, T, Decayed);
+ void *InsertPos = nullptr;
+ AdjustedType *AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ if (AT)
+ return QualType(AT, 0);
+
QualType Canonical = getCanonicalType(Decayed);
// Get the new insert position for the node we care about.
- DecayedType *NewIP = DecayedTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ AT = AdjustedTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(!AT && "Shouldn't be in the map!");
- DecayedType *New =
- new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
- Types.push_back(New);
- DecayedTypes.InsertNode(New, InsertPos);
- return QualType(New, 0);
+ AT = new (*this, TypeAlignment) DecayedType(T, Decayed, Canonical);
+ Types.push_back(AT);
+ AdjustedTypes.InsertNode(AT, InsertPos);
+ return QualType(AT, 0);
}
/// getBlockPointerType - Return the uniqued reference to the type for
@@ -2211,7 +2235,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
llvm::FoldingSetNodeID ID;
BlockPointerType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (BlockPointerType *PT =
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2225,7 +2249,7 @@ QualType ASTContext::getBlockPointerType(QualType T) const {
// Get the new insert position for the node we care about.
BlockPointerType *NewIP =
BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
BlockPointerType *New
= new (*this, TypeAlignment) BlockPointerType(T, Canonical);
@@ -2246,7 +2270,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
llvm::FoldingSetNodeID ID;
ReferenceType::Profile(ID, T, SpelledAsLValue);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (LValueReferenceType *RT =
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
@@ -2263,7 +2287,7 @@ ASTContext::getLValueReferenceType(QualType T, bool SpelledAsLValue) const {
// Get the new insert position for the node we care about.
LValueReferenceType *NewIP =
LValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
LValueReferenceType *New
@@ -2283,7 +2307,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
llvm::FoldingSetNodeID ID;
ReferenceType::Profile(ID, T, false);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (RValueReferenceType *RT =
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(RT, 0);
@@ -2300,7 +2324,7 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
// Get the new insert position for the node we care about.
RValueReferenceType *NewIP =
RValueReferenceTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
RValueReferenceType *New
@@ -2318,7 +2342,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
llvm::FoldingSetNodeID ID;
MemberPointerType::Profile(ID, T, Cls);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (MemberPointerType *PT =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
@@ -2332,7 +2356,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) const {
// Get the new insert position for the node we care about.
MemberPointerType *NewIP =
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
MemberPointerType *New
= new (*this, TypeAlignment) MemberPointerType(T, Cls, Canonical);
@@ -2360,7 +2384,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
llvm::FoldingSetNodeID ID;
ConstantArrayType::Profile(ID, EltTy, ArySize, ASM, IndexTypeQuals);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ConstantArrayType *ATP =
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(ATP, 0);
@@ -2377,7 +2401,7 @@ QualType ASTContext::getConstantArrayType(QualType EltTy,
// Get the new insert position for the node we care about.
ConstantArrayType *NewIP =
ConstantArrayTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ConstantArrayType *New = new(*this,TypeAlignment)
@@ -2495,7 +2519,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
const IncompleteArrayType *iat = cast<IncompleteArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(iat->getElementType()),
- /*size*/ 0,
+ /*size*/ nullptr,
ArrayType::Normal,
iat->getIndexTypeCVRQualifiers(),
SourceRange());
@@ -2507,7 +2531,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
const VariableArrayType *vat = cast<VariableArrayType>(ty);
result = getVariableArrayType(
getVariableArrayDecayedType(vat->getElementType()),
- /*size*/ 0,
+ /*size*/ nullptr,
ArrayType::Star,
vat->getIndexTypeCVRQualifiers(),
vat->getBracketsRange());
@@ -2577,7 +2601,7 @@ QualType ASTContext::getDependentSizedArrayType(QualType elementType,
SplitQualType canonElementType = getCanonicalType(elementType).split();
- void *insertPos = 0;
+ void *insertPos = nullptr;
llvm::FoldingSetNodeID ID;
DependentSizedArrayType::Profile(ID, *this,
QualType(canonElementType.Ty, 0),
@@ -2622,7 +2646,7 @@ QualType ASTContext::getIncompleteArrayType(QualType elementType,
llvm::FoldingSetNodeID ID;
IncompleteArrayType::Profile(ID, elementType, ASM, elementTypeQuals);
- void *insertPos = 0;
+ void *insertPos = nullptr;
if (IncompleteArrayType *iat =
IncompleteArrayTypes.FindNodeOrInsertPos(ID, insertPos))
return QualType(iat, 0);
@@ -2662,7 +2686,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts, Type::Vector, VecKind);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -2674,7 +2698,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
VectorType *New = new (*this, TypeAlignment)
VectorType(vecType, NumElts, Canonical, VecKind);
@@ -2693,7 +2717,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts, Type::ExtVector,
VectorType::GenericVector);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@@ -2705,7 +2729,7 @@ ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) const {
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
ExtVectorType *New = new (*this, TypeAlignment)
ExtVectorType(vecType, NumElts, Canonical);
@@ -2722,7 +2746,7 @@ ASTContext::getDependentSizedExtVectorType(QualType vecType,
DependentSizedExtVectorType::Profile(ID, *this, getCanonicalType(vecType),
SizeExpr);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentSizedExtVectorType *Canon
= DependentSizedExtVectorTypes.FindNodeOrInsertPos(ID, InsertPos);
DependentSizedExtVectorType *New;
@@ -2768,7 +2792,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
llvm::FoldingSetNodeID ID;
FunctionNoProtoType::Profile(ID, ResultTy, Info);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (FunctionNoProtoType *FT =
FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FT, 0);
@@ -2780,7 +2804,7 @@ ASTContext::getFunctionNoProtoType(QualType ResultTy,
// Get the new insert position for the node we care about.
FunctionNoProtoType *NewIP =
FunctionNoProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
FunctionProtoType::ExtInfo newInfo = Info.withCallingConv(CallConv);
@@ -2798,8 +2822,6 @@ static bool isCanonicalResultType(QualType T) {
T.getObjCLifetime() == Qualifiers::OCL_ExplicitNone);
}
-/// getFunctionType - Return a normal function type with a typed argument
-/// list. isVariadic indicates whether the argument list includes '...'.
QualType
ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
const FunctionProtoType::ExtProtoInfo &EPI) const {
@@ -2811,7 +2833,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
FunctionProtoType::Profile(ID, ResultTy, ArgArray.begin(), NumArgs, EPI,
*this);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (FunctionProtoType *FTP =
FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(FTP, 0);
@@ -2851,7 +2873,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
// Get the new insert position for the node we care about.
FunctionProtoType *NewIP =
FunctionProtoTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
// FunctionProtoType objects are allocated with extra bytes after
@@ -2873,7 +2895,7 @@ ASTContext::getFunctionType(QualType ResultTy, ArrayRef<QualType> ArgArray,
} else if (EPI.ExceptionSpecType == EST_Unevaluated) {
Size += sizeof(FunctionDecl*);
}
- if (EPI.ConsumedArguments)
+ if (EPI.ConsumedParameters)
Size += NumArgs * sizeof(bool);
FunctionProtoType *FTP = (FunctionProtoType*) Allocate(Size, TypeAlignment);
@@ -2995,7 +3017,7 @@ QualType ASTContext::getAttributedType(AttributedType::Kind attrKind,
llvm::FoldingSetNodeID id;
AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
- void *insertPos = 0;
+ void *insertPos = nullptr;
AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
if (type) return QualType(type, 0);
@@ -3019,7 +3041,7 @@ ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm,
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmType::Profile(ID, Parm, Replacement);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
SubstTemplateTypeParmType *SubstParm
= SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3038,17 +3060,15 @@ QualType ASTContext::getSubstTemplateTypeParmPackType(
const TemplateTypeParmType *Parm,
const TemplateArgument &ArgPack) {
#ifndef NDEBUG
- for (TemplateArgument::pack_iterator P = ArgPack.pack_begin(),
- PEnd = ArgPack.pack_end();
- P != PEnd; ++P) {
- assert(P->getKind() == TemplateArgument::Type &&"Pack contains a non-type");
- assert(P->getAsType().isCanonical() && "Pack contains non-canonical type");
+ for (const auto &P : ArgPack.pack_elements()) {
+ assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type");
+ assert(P.getAsType().isCanonical() && "Pack contains non-canonical type");
}
#endif
llvm::FoldingSetNodeID ID;
SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (SubstTemplateTypeParmPackType *SubstParm
= SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(SubstParm, 0);
@@ -3077,7 +3097,7 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
TemplateTypeParmDecl *TTPDecl) const {
llvm::FoldingSetNodeID ID;
TemplateTypeParmType::Profile(ID, Depth, Index, ParameterPack, TTPDecl);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
TemplateTypeParmType *TypeParm
= TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3218,7 +3238,7 @@ ASTContext::getCanonicalTemplateSpecializationType(TemplateName Template,
TemplateSpecializationType::Profile(ID, CanonTemplate,
CanonArgs.data(), NumArgs, *this);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
TemplateSpecializationType *Spec
= TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -3246,7 +3266,7 @@ ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
llvm::FoldingSetNodeID ID;
ElaboratedType::Profile(ID, Keyword, NNS, NamedType);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
@@ -3270,7 +3290,7 @@ ASTContext::getParenType(QualType InnerType) const {
llvm::FoldingSetNodeID ID;
ParenType::Profile(ID, InnerType);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ParenType *T = ParenTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
return QualType(T, 0);
@@ -3293,8 +3313,6 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
QualType Canon) const {
- assert(NNS->isDependent() && "nested-name-specifier must be dependent");
-
if (Canon.isNull()) {
NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
ElaboratedTypeKeyword CanonKeyword = Keyword;
@@ -3308,7 +3326,7 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
llvm::FoldingSetNodeID ID;
DependentNameType::Profile(ID, Keyword, NNS, Name);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentNameType *T
= DependentNameTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3349,7 +3367,7 @@ ASTContext::getDependentTemplateSpecializationType(
DependentTemplateSpecializationType::Profile(ID, *this, Keyword, NNS,
Name, NumArgs, Args);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTemplateSpecializationType *T
= DependentTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3395,7 +3413,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
assert(Pattern->containsUnexpandedParameterPack() &&
"Pack expansions must expand one or more parameter packs");
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
PackExpansionType *T
= PackExpansionTypes.FindNodeOrInsertPos(ID, InsertPos);
if (T)
@@ -3408,7 +3426,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
// contains an alias template specialization which ignores one of its
// parameters.
if (Canon->containsUnexpandedParameterPack()) {
- Canon = getPackExpansionType(getCanonicalType(Pattern), NumExpansions);
+ Canon = getPackExpansionType(Canon, NumExpansions);
// Find the insert position again, in case we inserted an element into
// PackExpansionTypes and invalidated our insert position.
@@ -3419,7 +3437,7 @@ QualType ASTContext::getPackExpansionType(QualType Pattern,
T = new (*this) PackExpansionType(Pattern, Canon, NumExpansions);
Types.push_back(T);
PackExpansionTypes.InsertNode(T, InsertPos);
- return QualType(T, 0);
+ return QualType(T, 0);
}
/// CmpProtocolNames - Comparison predicate for sorting protocols
@@ -3470,7 +3488,7 @@ QualType ASTContext::getObjCObjectType(QualType BaseType,
// Look in the folding set for an existing type.
llvm::FoldingSetNodeID ID;
ObjCObjectTypeImpl::Profile(ID, BaseType, Protocols, NumProtocols);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ObjCObjectType *QT = ObjCObjectTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
@@ -3507,13 +3525,79 @@ QualType ASTContext::getObjCObjectType(QualType BaseType,
return QualType(T, 0);
}
+/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
+/// protocol list adopt all protocols in QT's qualified-id protocol
+/// list.
+bool ASTContext::ObjCObjectAdoptsQTypeProtocols(QualType QT,
+ ObjCInterfaceDecl *IC) {
+ if (!QT->isObjCQualifiedIdType())
+ return false;
+
+ if (const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>()) {
+ // If both the right and left sides have qualifiers.
+ for (auto *Proto : OPT->quals()) {
+ if (!IC->ClassImplementsProtocol(Proto, false))
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+/// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+/// QT's qualified-id protocol list adopt all protocols in IDecl's list
+/// of protocols.
+bool ASTContext::QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+ ObjCInterfaceDecl *IDecl) {
+ if (!QT->isObjCQualifiedIdType())
+ return false;
+ const ObjCObjectPointerType *OPT = QT->getAs<ObjCObjectPointerType>();
+ if (!OPT)
+ return false;
+ if (!IDecl->hasDefinition())
+ return false;
+ llvm::SmallPtrSet<ObjCProtocolDecl *, 8> InheritedProtocols;
+ CollectInheritedProtocols(IDecl, InheritedProtocols);
+ if (InheritedProtocols.empty())
+ return false;
+ // Check that if every protocol in list of id<plist> conforms to a protcol
+ // of IDecl's, then bridge casting is ok.
+ bool Conforms = false;
+ for (auto *Proto : OPT->quals()) {
+ Conforms = false;
+ for (auto *PI : InheritedProtocols) {
+ if (ProtocolCompatibleWithProtocol(Proto, PI)) {
+ Conforms = true;
+ break;
+ }
+ }
+ if (!Conforms)
+ break;
+ }
+ if (Conforms)
+ return true;
+
+ for (auto *PI : InheritedProtocols) {
+ // If both the right and left sides have qualifiers.
+ bool Adopts = false;
+ for (auto *Proto : OPT->quals()) {
+ // return 'true' if 'PI' is in the inheritance hierarchy of Proto
+ if ((Adopts = ProtocolCompatibleWithProtocol(PI, Proto)))
+ break;
+ }
+ if (!Adopts)
+ return false;
+ }
+ return true;
+}
+
/// getObjCObjectPointerType - Return a ObjCObjectPointerType type for
/// the given object type.
QualType ASTContext::getObjCObjectPointerType(QualType ObjectT) const {
llvm::FoldingSetNodeID ID;
ObjCObjectPointerType::Profile(ID, ObjectT);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (ObjCObjectPointerType *QT =
ObjCObjectPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(QT, 0);
@@ -3572,7 +3656,7 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
llvm::FoldingSetNodeID ID;
DependentTypeOfExprType::Profile(ID, *this, tofExpr);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTypeOfExprType *Canon
= DependentTypeOfExprTypes.FindNodeOrInsertPos(ID, InsertPos);
if (Canon) {
@@ -3596,10 +3680,10 @@ QualType ASTContext::getTypeOfExprType(Expr *tofExpr) const {
}
/// getTypeOfType - Unlike many "get<Type>" functions, we don't unique
-/// TypeOfType AST's. The only motivation to unique these nodes would be
+/// TypeOfType nodes. The only motivation to unique these nodes would be
/// memory savings. Since typeof(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical type's (which are always unique).
+/// an issue. This doesn't affect the type checker, since it operates
+/// on canonical types (which are always unique).
QualType ASTContext::getTypeOfType(QualType tofType) const {
QualType Canonical = getCanonicalType(tofType);
TypeOfType *tot = new (*this, TypeAlignment) TypeOfType(tofType, Canonical);
@@ -3608,39 +3692,34 @@ QualType ASTContext::getTypeOfType(QualType tofType) const {
}
-/// getDecltypeType - Unlike many "get<Type>" functions, we don't unique
-/// DecltypeType AST's. The only motivation to unique these nodes would be
-/// memory savings. Since decltype(t) is fairly uncommon, space shouldn't be
-/// an issue. This doesn't effect the type checker, since it operates
-/// on canonical types (which are always unique).
+/// \brief Unlike many "get<Type>" functions, we don't unique DecltypeType
+/// nodes. This would never be helpful, since each such type has its own
+/// expression, and would not give a significant memory saving, since there
+/// is an Expr tree under each such type.
QualType ASTContext::getDecltypeType(Expr *e, QualType UnderlyingType) const {
DecltypeType *dt;
-
- // C++0x [temp.type]p2:
+
+ // C++11 [temp.type]p2:
// If an expression e involves a template parameter, decltype(e) denotes a
- // unique dependent type. Two such decltype-specifiers refer to the same
- // type only if their expressions are equivalent (14.5.6.1).
+ // unique dependent type. Two such decltype-specifiers refer to the same
+ // type only if their expressions are equivalent (14.5.6.1).
if (e->isInstantiationDependent()) {
llvm::FoldingSetNodeID ID;
DependentDecltypeType::Profile(ID, *this, e);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentDecltypeType *Canon
= DependentDecltypeTypes.FindNodeOrInsertPos(ID, InsertPos);
- if (Canon) {
- // We already have a "canonical" version of an equivalent, dependent
- // decltype type. Use that as our canonical type.
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- QualType((DecltypeType*)Canon, 0));
- } else {
+ if (!Canon) {
// Build a new, canonical typeof(expr) type.
Canon = new (*this, TypeAlignment) DependentDecltypeType(*this, e);
DependentDecltypeTypes.InsertNode(Canon, InsertPos);
- dt = Canon;
}
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, QualType((DecltypeType *)Canon, 0));
} else {
- dt = new (*this, TypeAlignment) DecltypeType(e, UnderlyingType,
- getCanonicalType(UnderlyingType));
+ dt = new (*this, TypeAlignment)
+ DecltypeType(e, UnderlyingType, getCanonicalType(UnderlyingType));
}
Types.push_back(dt);
return QualType(dt, 0);
@@ -3670,7 +3749,7 @@ QualType ASTContext::getAutoType(QualType DeducedType, bool IsDecltypeAuto,
return getAutoDeductType();
// Look in the folding set for an existing type.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
llvm::FoldingSetNodeID ID;
AutoType::Profile(ID, DeducedType, IsDecltypeAuto, IsDependent);
if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
@@ -3693,7 +3772,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
llvm::FoldingSetNodeID ID;
AtomicType::Profile(ID, T);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(AT, 0);
@@ -3705,7 +3784,7 @@ QualType ASTContext::getAtomicType(QualType T) const {
// Get the new insert position for the node we care about.
AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ assert(!NewIP && "Shouldn't be in the map!"); (void)NewIP;
}
AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
Types.push_back(New);
@@ -4064,7 +4143,7 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
NestedNameSpecifier *
ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
if (!NNS)
- return 0;
+ return nullptr;
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
@@ -4076,13 +4155,13 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
case NestedNameSpecifier::Namespace:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, 0,
+ return NestedNameSpecifier::Create(*this, nullptr,
NNS->getAsNamespace()->getOriginalNamespace());
case NestedNameSpecifier::NamespaceAlias:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, 0,
+ return NestedNameSpecifier::Create(*this, nullptr,
NNS->getAsNamespaceAlias()->getNamespace()
->getOriginalNamespace());
@@ -4104,8 +4183,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
// Otherwise, just canonicalize the type, and force it to be a TypeSpec.
// FIXME: Why are TypeSpec and TypeSpecWithTemplate distinct in the
// first place?
- return NestedNameSpecifier::Create(*this, 0, false,
- const_cast<Type*>(T.getTypePtr()));
+ return NestedNameSpecifier::Create(*this, nullptr, false,
+ const_cast<Type *>(T.getTypePtr()));
}
case NestedNameSpecifier::Global:
@@ -4127,7 +4206,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the common negative case fast.
if (!isa<ArrayType>(T.getCanonicalType()))
- return 0;
+ return nullptr;
// Apply any qualifiers from the array type to the element type. This
// implements C99 6.7.3p8: "If the specification of an array type includes
@@ -4142,7 +4221,7 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// If we have a simple case, just return now.
const ArrayType *ATy = dyn_cast<ArrayType>(split.Ty);
- if (ATy == 0 || qs.empty())
+ if (!ATy || qs.empty())
return ATy;
// Otherwise, we have an array and we have qualifiers on it. Push the
@@ -4428,7 +4507,7 @@ static const Type *getIntegerTypeForEnum(const EnumType *ET) {
// FIXME: In C++, enum types are never integer types.
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
return ET->getDecl()->getIntegerType().getTypePtr();
- return NULL;
+ return nullptr;
}
/// getIntegerTypeOrder - Returns the highest ranked integer type:
@@ -4479,22 +4558,10 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
return 1;
}
-static RecordDecl *
-CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK,
- DeclContext *DC, IdentifierInfo *Id) {
- SourceLocation Loc;
- if (Ctx.getLangOpts().CPlusPlus)
- return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
- else
- return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id);
-}
-
// getCFConstantStringType - Return the type used for constant CFStrings.
QualType ASTContext::getCFConstantStringType() const {
if (!CFConstantStringTypeDecl) {
- CFConstantStringTypeDecl =
- CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("NSConstantString"));
+ CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString");
CFConstantStringTypeDecl->startDefinition();
QualType FieldTypes[4];
@@ -4512,9 +4579,9 @@ QualType ASTContext::getCFConstantStringType() const {
for (unsigned i = 0; i < 4; ++i) {
FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
SourceLocation(),
- SourceLocation(), 0,
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ SourceLocation(), nullptr,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -4529,8 +4596,7 @@ QualType ASTContext::getCFConstantStringType() const {
QualType ASTContext::getObjCSuperType() const {
if (ObjCSuperType.isNull()) {
- RecordDecl *ObjCSuperTypeDecl =
- CreateRecordDecl(*this, TTK_Struct, TUDecl, &Idents.get("objc_super"));
+ RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super");
TUDecl->addDecl(ObjCSuperTypeDecl);
ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl);
}
@@ -4547,12 +4613,11 @@ QualType ASTContext::getBlockDescriptorType() const {
if (BlockDescriptorType)
return getTagDeclType(BlockDescriptorType);
- RecordDecl *T;
+ RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
- T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("__block_descriptor"));
- T->startDefinition();
-
+ RD = buildImplicitRecord("__block_descriptor");
+ RD->startDefinition();
+
QualType FieldTypes[] = {
UnsignedLongTy,
UnsignedLongTy,
@@ -4564,20 +4629,17 @@ QualType ASTContext::getBlockDescriptorType() const {
};
for (size_t i = 0; i < 2; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
- /*Mutable=*/false,
- ICIS_NoInit);
+ FieldDecl *Field = FieldDecl::Create(
+ *this, RD, SourceLocation(), SourceLocation(),
+ &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr, /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
- T->addDecl(Field);
+ RD->addDecl(Field);
}
- T->completeDefinition();
+ RD->completeDefinition();
- BlockDescriptorType = T;
+ BlockDescriptorType = RD;
return getTagDeclType(BlockDescriptorType);
}
@@ -4586,12 +4648,11 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
if (BlockDescriptorExtendedType)
return getTagDeclType(BlockDescriptorExtendedType);
- RecordDecl *T;
+ RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
- T = CreateRecordDecl(*this, TTK_Struct, TUDecl,
- &Idents.get("__block_descriptor_withcopydispose"));
- T->startDefinition();
-
+ RD = buildImplicitRecord("__block_descriptor_withcopydispose");
+ RD->startDefinition();
+
QualType FieldTypes[] = {
UnsignedLongTy,
UnsignedLongTy,
@@ -4607,21 +4668,18 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
};
for (size_t i = 0; i < 4; ++i) {
- FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
- SourceLocation(),
- &Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
- /*Mutable=*/false,
- ICIS_NoInit);
+ FieldDecl *Field = FieldDecl::Create(
+ *this, RD, SourceLocation(), SourceLocation(),
+ &Idents.get(FieldNames[i]), FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
+ /*Mutable=*/false, ICIS_NoInit);
Field->setAccess(AS_public);
- T->addDecl(Field);
+ RD->addDecl(Field);
}
- T->completeDefinition();
-
- BlockDescriptorExtendedType = T;
+ RD->completeDefinition();
+ BlockDescriptorExtendedType = RD;
return getTagDeclType(BlockDescriptorExtendedType);
}
@@ -4691,12 +4749,8 @@ bool ASTContext::getByrefLifetime(QualType Ty,
TypedefDecl *ASTContext::getObjCInstanceTypeDecl() {
if (!ObjCInstanceTypeDecl)
- ObjCInstanceTypeDecl = TypedefDecl::Create(*this,
- getTranslationUnitDecl(),
- SourceLocation(),
- SourceLocation(),
- &Idents.get("instancetype"),
- getTrivialTypeSourceInfo(getObjCIdType()));
+ ObjCInstanceTypeDecl =
+ buildImplicitTypedef(getObjCIdType(), "instancetype");
return ObjCInstanceTypeDecl;
}
@@ -4727,6 +4781,12 @@ CharUnits ASTContext::getObjCEncodingTypeSize(QualType type) const {
return sz;
}
+bool ASTContext::isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const {
+ return getLangOpts().MSVCCompat && VD->isStaticDataMember() &&
+ VD->getType()->isIntegralOrEnumerationType() &&
+ !VD->getFirstDecl()->isOutOfLine() && VD->getFirstDecl()->hasInit();
+}
+
static inline
std::string charUnitsToString(const CharUnits &CU) {
return llvm::itostr(CU.getQuantity());
@@ -4742,21 +4802,19 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
Expr->getType()->getAs<BlockPointerType>()->getPointeeType();
// Encode result type.
if (getLangOpts().EncodeExtendedBlockSig)
- getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None,
- BlockTy->getAs<FunctionType>()->getResultType(),
- S, true /*Extended*/);
+ getObjCEncodingForMethodParameter(
+ Decl::OBJC_TQ_None, BlockTy->getAs<FunctionType>()->getReturnType(), S,
+ true /*Extended*/);
else
- getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getResultType(),
- S);
+ getObjCEncodingForType(BlockTy->getAs<FunctionType>()->getReturnType(), S);
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
SourceLocation Loc;
CharUnits PtrSize = getTypeSizeInChars(VoidPtrTy);
CharUnits ParmOffset = PtrSize;
- for (BlockDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- QualType PType = (*PI)->getType();
+ for (auto PI : Decl->params()) {
+ QualType PType = PI->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
@@ -4770,9 +4828,7 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
// Argument types.
ParmOffset = PtrSize;
- for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E =
- Decl->param_end(); PI != E; ++PI) {
- ParmVarDecl *PVDecl = *PI;
+ for (auto PVDecl : Decl->params()) {
QualType PType = PVDecl->getOriginalType();
if (const ArrayType *AT =
dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4797,12 +4853,11 @@ std::string ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr) const {
bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
std::string& S) {
// Encode result type.
- getObjCEncodingForType(Decl->getResultType(), S);
+ getObjCEncodingForType(Decl->getReturnType(), S);
CharUnits ParmOffset;
// Compute size of all parameters.
- for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- QualType PType = (*PI)->getType();
+ for (auto PI : Decl->params()) {
+ QualType PType = PI->getType();
CharUnits sz = getObjCEncodingTypeSize(PType);
if (sz.isZero())
continue;
@@ -4815,9 +4870,7 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl,
ParmOffset = CharUnits::Zero();
// Argument types.
- for (FunctionDecl::param_const_iterator PI = Decl->param_begin(),
- E = Decl->param_end(); PI != E; ++PI) {
- ParmVarDecl *PVDecl = *PI;
+ for (auto PVDecl : Decl->params()) {
QualType PType = PVDecl->getOriginalType();
if (const ArrayType *AT =
dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) {
@@ -4844,7 +4897,7 @@ 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, 0,
+ getObjCEncodingForTypeImpl(T, S, true, true, nullptr,
true /*OutermostType*/,
false /*EncodingProperty*/,
false /*StructField*/,
@@ -4859,8 +4912,8 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
bool Extended) const {
// FIXME: This is not very efficient.
// Encode return type.
- getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),
- Decl->getResultType(), S, Extended);
+ getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(),
+ Decl->getReturnType(), S, Extended);
// Compute size of all parameters.
// Start with computing size of a pointer in number of bytes.
// FIXME: There might(should) be a better way of doing this computation!
@@ -4907,6 +4960,26 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl,
return false;
}
+ObjCPropertyImplDecl *
+ASTContext::getObjCPropertyImplDeclForPropertyDecl(
+ const ObjCPropertyDecl *PD,
+ const Decl *Container) const {
+ if (!Container)
+ return nullptr;
+ if (const ObjCCategoryImplDecl *CID =
+ dyn_cast<ObjCCategoryImplDecl>(Container)) {
+ for (auto *PID : CID->property_impls())
+ if (PID->getPropertyDecl() == PD)
+ return PID;
+ } else {
+ const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
+ for (auto *PID : OID->property_impls())
+ if (PID->getPropertyDecl() == PD)
+ return PID;
+ }
+ return nullptr;
+}
+
/// getObjCEncodingForPropertyDecl - Return the encoded type for this
/// property declaration. If non-NULL, Container must be either an
/// ObjCCategoryImplDecl or ObjCImplementationDecl; it should only be
@@ -4937,39 +5010,14 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
std::string& S) const {
// Collect information from the property implementation decl(s).
bool Dynamic = false;
- ObjCPropertyImplDecl *SynthesizePID = 0;
-
- // FIXME: Duplicated code due to poor abstraction.
- if (Container) {
- if (const ObjCCategoryImplDecl *CID =
- dyn_cast<ObjCCategoryImplDecl>(Container)) {
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = CID->propimpl_begin(), e = CID->propimpl_end();
- i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- } else {
- const ObjCImplementationDecl *OID=cast<ObjCImplementationDecl>(Container);
- for (ObjCCategoryImplDecl::propimpl_iterator
- i = OID->propimpl_begin(), e = OID->propimpl_end();
- i != e; ++i) {
- ObjCPropertyImplDecl *PID = *i;
- if (PID->getPropertyDecl() == PD) {
- if (PID->getPropertyImplementation()==ObjCPropertyImplDecl::Dynamic) {
- Dynamic = true;
- } else {
- SynthesizePID = PID;
- }
- }
- }
- }
+ ObjCPropertyImplDecl *SynthesizePID = nullptr;
+
+ if (ObjCPropertyImplDecl *PropertyImpDecl =
+ getObjCPropertyImplDeclForPropertyDecl(PD, Container)) {
+ if (PropertyImpDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ Dynamic = true;
+ else
+ SynthesizePID = PropertyImpDecl;
}
// FIXME: This is not very efficient.
@@ -4978,9 +5026,7 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
// Encode result type.
// GCC has some special rules regarding encoding of properties which
// closely resembles encoding of ivars.
- getObjCEncodingForTypeImpl(PD->getType(), S, true, true, 0,
- true /* outermost type */,
- true /* encoding for property */);
+ getObjCEncodingForPropertyType(PD->getType(), S);
if (PD->isReadOnly()) {
S += ",R";
@@ -4988,6 +5034,8 @@ void ASTContext::getObjCEncodingForPropertyDecl(const ObjCPropertyDecl *PD,
S += ",C";
if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain)
S += ",&";
+ if (PD->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_weak)
+ S += ",W";
} else {
switch (PD->getSetterKind()) {
case ObjCPropertyDecl::Assign: break;
@@ -5051,6 +5099,16 @@ void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
true /* outermost type */);
}
+void ASTContext::getObjCEncodingForPropertyType(QualType T,
+ std::string& S) const {
+ // 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 */);
+}
+
static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
BuiltinType::Kind kind) {
switch (kind) {
@@ -5180,15 +5238,15 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
case Type::Complex: {
const ComplexType *CT = T->castAs<ComplexType>();
S += 'j';
- getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, 0, false,
- false);
+ getObjCEncodingForTypeImpl(CT->getElementType(), S, false, false, nullptr,
+ false, false);
return;
}
case Type::Atomic: {
const AtomicType *AT = T->castAs<AtomicType>();
S += 'A';
- getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, 0,
+ getObjCEncodingForTypeImpl(AT->getValueType(), S, false, false, nullptr,
false, false);
return;
}
@@ -5260,7 +5318,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
getLegacyIntegralTypeEncoding(PointeeTy);
getObjCEncodingForTypeImpl(PointeeTy, S, false, ExpandPointedToStructures,
- NULL);
+ nullptr);
return;
}
@@ -5322,9 +5380,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
if (!RDecl->isUnion()) {
getObjCEncodingForStructureImpl(RDecl, S, FD);
} else {
- for (RecordDecl::field_iterator Field = RDecl->field_begin(),
- FieldEnd = RDecl->field_end();
- Field != FieldEnd; ++Field) {
+ for (const auto *Field : RDecl->fields()) {
if (FD) {
S += '"';
S += Field->getNameAsString();
@@ -5334,7 +5390,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Special case bit-fields.
if (Field->isBitField()) {
getObjCEncodingForTypeImpl(Field->getType(), S, false, true,
- *Field);
+ Field);
} else {
QualType qt = Field->getType();
getLegacyIntegralTypeEncoding(qt);
@@ -5358,37 +5414,38 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
S += '<';
// Block return type
- getObjCEncodingForTypeImpl(FT->getResultType(), S,
- ExpandPointedToStructures, ExpandStructures,
- FD,
- false /* OutermostType */,
- EncodingProperty,
- false /* StructField */,
- EncodeBlockParameters,
- EncodeClassNames);
+ getObjCEncodingForTypeImpl(
+ FT->getReturnType(), S, ExpandPointedToStructures, ExpandStructures,
+ FD, false /* OutermostType */, EncodingProperty,
+ false /* StructField */, EncodeBlockParameters, EncodeClassNames);
// Block self
S += "@?";
// Block parameters
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) {
- for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(),
- E = FPT->arg_type_end(); I && (I != E); ++I) {
- getObjCEncodingForTypeImpl(*I, S,
- ExpandPointedToStructures,
- ExpandStructures,
- FD,
- false /* OutermostType */,
- EncodingProperty,
- false /* StructField */,
- EncodeBlockParameters,
- EncodeClassNames);
- }
+ for (const auto &I : FPT->param_types())
+ getObjCEncodingForTypeImpl(
+ I, S, ExpandPointedToStructures, ExpandStructures, FD,
+ false /* OutermostType */, EncodingProperty,
+ false /* StructField */, EncodeBlockParameters, EncodeClassNames);
}
S += '>';
}
return;
}
- case Type::ObjCObject:
+ case Type::ObjCObject: {
+ // hack to match legacy encoding of *id and *Class
+ QualType Ty = getObjCObjectPointerType(CT);
+ if (Ty->isObjCIdType()) {
+ S += "{objc_object=}";
+ return;
+ }
+ else if (Ty->isObjCClassType()) {
+ S += "{objc_class=}";
+ return;
+ }
+ }
+
case Type::ObjCInterface: {
// Ignore protocol qualifiers when mangling at this level.
T = T->castAs<ObjCObjectType>()->getBaseType();
@@ -5440,10 +5497,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
// Note that we do extended encoding of protocol qualifer list
// Only when doing ivar or property encoding.
S += '"';
- for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
- E = OPT->qual_end(); I != E; ++I) {
+ for (const auto *I : OPT->quals()) {
S += '<';
- S += (*I)->getNameAsString();
+ S += I->getNameAsString();
S += '>';
}
S += '"';
@@ -5475,7 +5531,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
}
getObjCEncodingForTypeImpl(PointeeTy, S,
false, ExpandPointedToStructures,
- NULL,
+ nullptr,
false, false, false, false, false,
/*EncodePointerToObjCTypedef*/true);
return;
@@ -5486,10 +5542,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
(FD || EncodingProperty || EncodeClassNames)) {
S += '"';
S += OPT->getInterfaceDecl()->getIdentifier()->getName();
- for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
- E = OPT->qual_end(); I != E; ++I) {
+ for (const auto *I : OPT->quals()) {
S += '<';
- S += (*I)->getNameAsString();
+ S += I->getNameAsString();
S += '>';
}
S += '"';
@@ -5542,11 +5597,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
const ASTRecordLayout &layout = getASTRecordLayout(RDecl);
if (CXXRec) {
- for (CXXRecordDecl::base_class_iterator
- BI = CXXRec->bases_begin(),
- BE = CXXRec->bases_end(); BI != BE; ++BI) {
- if (!BI->isVirtual()) {
- CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+ for (const auto &BI : CXXRec->bases()) {
+ if (!BI.isVirtual()) {
+ CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
if (base->isEmpty())
continue;
uint64_t offs = toBits(layout.getBaseClassOffset(base));
@@ -5566,10 +5619,8 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
}
if (CXXRec && includeVBases) {
- for (CXXRecordDecl::base_class_iterator
- BI = CXXRec->vbases_begin(),
- BE = CXXRec->vbases_end(); BI != BE; ++BI) {
- CXXRecordDecl *base = BI->getType()->getAsCXXRecordDecl();
+ for (const auto &BI : CXXRec->vbases()) {
+ CXXRecordDecl *base = BI.getType()->getAsCXXRecordDecl();
if (base->isEmpty())
continue;
uint64_t offs = toBits(layout.getVBaseClassOffset(base));
@@ -5587,7 +5638,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
size = layout.getSize();
}
+#ifndef NDEBUG
uint64_t CurOffs = 0;
+#endif
std::multimap<uint64_t, NamedDecl *>::iterator
CurLayObj = FieldOrBaseOffsets.begin();
@@ -5601,19 +5654,21 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
S += '"';
}
S += "^^?";
+#ifndef NDEBUG
CurOffs += getTypeSize(VoidPtrTy);
+#endif
}
if (!RDecl->hasFlexibleArrayMember()) {
// Mark the end of the structure.
uint64_t offs = toBits(size);
FieldOrBaseOffsets.insert(FieldOrBaseOffsets.upper_bound(offs),
- std::make_pair(offs, (NamedDecl*)0));
+ std::make_pair(offs, nullptr));
}
for (; CurLayObj != FieldOrBaseOffsets.end(); ++CurLayObj) {
+#ifndef NDEBUG
assert(CurOffs <= CurLayObj->first);
-
if (CurOffs < CurLayObj->first) {
uint64_t padding = CurLayObj->first - CurOffs;
// FIXME: There doesn't seem to be a way to indicate in the encoding that
@@ -5625,9 +5680,10 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
// longer then though.
CurOffs += padding;
}
+#endif
NamedDecl *dcl = CurLayObj->second;
- if (dcl == 0)
+ if (!dcl)
break; // reached end of structure.
if (CXXRecordDecl *base = dyn_cast<CXXRecordDecl>(dcl)) {
@@ -5637,7 +5693,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
// making the encoding type bigger than it really is.
getObjCEncodingForStructureImpl(base, S, FD, /*includeVBases*/false);
assert(!base->isEmpty());
+#ifndef NDEBUG
CurOffs += toBits(getASTRecordLayout(base).getNonVirtualSize());
+#endif
} else {
FieldDecl *field = cast<FieldDecl>(dcl);
if (FD) {
@@ -5648,7 +5706,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
if (field->isBitField()) {
EncodeBitField(this, S, field->getType(), field);
+#ifndef NDEBUG
CurOffs += field->getBitWidthValue(*this);
+#endif
} else {
QualType qt = field->getType();
getLegacyIntegralTypeEncoding(qt);
@@ -5656,7 +5716,9 @@ void ASTContext::getObjCEncodingForStructureImpl(RecordDecl *RDecl,
/*OutermostType*/false,
/*EncodingProperty*/false,
/*StructField*/true);
+#ifndef NDEBUG
CurOffs += getTypeSize(field->getType());
+#endif
}
}
}
@@ -5680,41 +5742,27 @@ void ASTContext::getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT,
TypedefDecl *ASTContext::getObjCIdDecl() const {
if (!ObjCIdDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinIdTy, 0, 0);
+ QualType T = getObjCObjectType(ObjCBuiltinIdTy, nullptr, 0);
T = getObjCObjectPointerType(T);
- TypeSourceInfo *IdInfo = getTrivialTypeSourceInfo(T);
- ObjCIdDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("id"), IdInfo);
+ ObjCIdDecl = buildImplicitTypedef(T, "id");
}
-
return ObjCIdDecl;
}
TypedefDecl *ASTContext::getObjCSelDecl() const {
if (!ObjCSelDecl) {
- QualType SelT = getPointerType(ObjCBuiltinSelTy);
- TypeSourceInfo *SelInfo = getTrivialTypeSourceInfo(SelT);
- ObjCSelDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("SEL"), SelInfo);
+ QualType T = getPointerType(ObjCBuiltinSelTy);
+ ObjCSelDecl = buildImplicitTypedef(T, "SEL");
}
return ObjCSelDecl;
}
TypedefDecl *ASTContext::getObjCClassDecl() const {
if (!ObjCClassDecl) {
- QualType T = getObjCObjectType(ObjCBuiltinClassTy, 0, 0);
+ QualType T = getObjCObjectType(ObjCBuiltinClassTy, nullptr, 0);
T = getObjCObjectPointerType(T);
- TypeSourceInfo *ClassInfo = getTrivialTypeSourceInfo(T);
- ObjCClassDecl = TypedefDecl::Create(const_cast<ASTContext &>(*this),
- getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Idents.get("Class"), ClassInfo);
+ ObjCClassDecl = buildImplicitTypedef(T, "Class");
}
-
return ObjCClassDecl;
}
@@ -5724,7 +5772,7 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
= ObjCInterfaceDecl::Create(*this, getTranslationUnitDecl(),
SourceLocation(),
&Idents.get("Protocol"),
- /*PrevDecl=*/0,
+ /*PrevDecl=*/nullptr,
SourceLocation(), true);
}
@@ -5737,56 +5785,30 @@ ObjCInterfaceDecl *ASTContext::getObjCProtocolDecl() const {
static TypedefDecl *CreateCharPtrBuiltinVaListDecl(const ASTContext *Context) {
// typedef char* __builtin_va_list;
- QualType CharPtrType = Context->getPointerType(Context->CharTy);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(CharPtrType);
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypeDecl;
+ QualType T = Context->getPointerType(Context->CharTy);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *CreateVoidPtrBuiltinVaListDecl(const ASTContext *Context) {
// typedef void* __builtin_va_list;
- QualType VoidPtrType = Context->getPointerType(Context->VoidTy);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VoidPtrType);
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypeDecl;
+ QualType T = Context->getPointerType(Context->VoidTy);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *
CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
- RecordDecl *VaListTagDecl;
+ // struct __va_list
+ RecordDecl *VaListTagDecl = Context->buildImplicitRecord("__va_list");
if (Context->getLangOpts().CPlusPlus) {
// namespace std { struct __va_list {
NamespaceDecl *NS;
NS = NamespaceDecl::Create(const_cast<ASTContext &>(*Context),
Context->getTranslationUnitDecl(),
- /*Inline*/false, SourceLocation(),
+ /*Inline*/ false, SourceLocation(),
SourceLocation(), &Context->Idents.get("std"),
- /*PrevDecl*/0);
-
- VaListTagDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list"));
+ /*PrevDecl*/ nullptr);
+ NS->setImplicit();
VaListTagDecl->setDeclContext(NS);
- } else {
- // struct __va_list
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list"));
}
VaListTagDecl->startDefinition();
@@ -5822,8 +5844,8 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5834,23 +5856,14 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __builtin_va_list;
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
}
static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 5;
@@ -5883,8 +5896,8 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5895,12 +5908,9 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -5909,25 +5919,14 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal, 0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *
CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 4;
@@ -5957,8 +5956,8 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -5969,12 +5968,9 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
+
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -5983,16 +5979,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal,0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
@@ -6001,19 +5988,13 @@ static TypedefDecl *CreatePNaClABIBuiltinVaListDecl(const ASTContext *Context) {
QualType IntArrayType
= Context->getConstantArrayType(Context->IntTy,
Size, ArrayType::Normal, 0);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- Context->getTrivialTypeSourceInfo(IntArrayType));
-
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(IntArrayType, "__builtin_va_list");
}
static TypedefDecl *
CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
- RecordDecl *VaListDecl;
+ // struct __va_list
+ RecordDecl *VaListDecl = Context->buildImplicitRecord("__va_list");
if (Context->getLangOpts().CPlusPlus) {
// namespace std { struct __va_list {
NamespaceDecl *NS;
@@ -6021,20 +6002,9 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
Context->getTranslationUnitDecl(),
/*Inline*/false, SourceLocation(),
SourceLocation(), &Context->Idents.get("std"),
- /*PrevDecl*/0);
-
- VaListDecl = CXXRecordDecl::Create(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list"));
-
+ /*PrevDecl*/ nullptr);
+ NS->setImplicit();
VaListDecl->setDeclContext(NS);
-
- } else {
- // struct __va_list {
- VaListDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list"));
}
VaListDecl->startDefinition();
@@ -6046,8 +6016,8 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
&Context->Idents.get("__ap"),
Context->getPointerType(Context->VoidTy),
- /*TInfo=*/0,
- /*BitWidth=*/0,
+ /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -6057,26 +6027,15 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
VaListDecl->completeDefinition();
// typedef struct __va_list __builtin_va_list;
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(Context->getRecordType(VaListDecl));
-
- TypedefDecl *VaListTypeDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
-
- return VaListTypeDecl;
+ QualType T = Context->getRecordType(VaListDecl);
+ return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
static TypedefDecl *
CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
// typedef struct __va_list_tag {
RecordDecl *VaListTagDecl;
- VaListTagDecl = CreateRecordDecl(*Context, TTK_Struct,
- Context->getTranslationUnitDecl(),
- &Context->Idents.get("__va_list_tag"));
+ VaListTagDecl = Context->buildImplicitRecord("__va_list_tag");
VaListTagDecl->startDefinition();
const size_t NumFields = 4;
@@ -6106,8 +6065,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
SourceLocation(),
SourceLocation(),
&Context->Idents.get(FieldNames[i]),
- FieldTypes[i], /*TInfo=*/0,
- /*BitWidth=*/0,
+ FieldTypes[i], /*TInfo=*/nullptr,
+ /*BitWidth=*/nullptr,
/*Mutable=*/false,
ICIS_NoInit);
Field->setAccess(AS_public);
@@ -6118,12 +6077,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagTy = VaListTagType;
// } __va_list_tag;
- TypedefDecl *VaListTagTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__va_list_tag"),
- Context->getTrivialTypeSourceInfo(VaListTagType));
+ TypedefDecl *VaListTagTypedefDecl =
+ Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
QualType VaListTagTypedefType =
Context->getTypedefType(VaListTagTypedefDecl);
@@ -6132,16 +6087,8 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
QualType VaListTagArrayType
= Context->getConstantArrayType(VaListTagTypedefType,
Size, ArrayType::Normal,0);
- TypeSourceInfo *TInfo
- = Context->getTrivialTypeSourceInfo(VaListTagArrayType);
- TypedefDecl *VaListTypedefDecl
- = TypedefDecl::Create(const_cast<ASTContext &>(*Context),
- Context->getTranslationUnitDecl(),
- SourceLocation(), SourceLocation(),
- &Context->Idents.get("__builtin_va_list"),
- TInfo);
- return VaListTypedefDecl;
+ return Context->buildImplicitTypedef(VaListTagArrayType, "__builtin_va_list");
}
static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
@@ -6169,8 +6116,10 @@ static TypedefDecl *CreateVaListDecl(const ASTContext *Context,
}
TypedefDecl *ASTContext::getBuiltinVaListDecl() const {
- if (!BuiltinVaListDecl)
+ if (!BuiltinVaListDecl) {
BuiltinVaListDecl = CreateVaListDecl(this, Target->getBuiltinVaListKind());
+ assert(BuiltinVaListDecl->isImplicit());
+ }
return BuiltinVaListDecl;
}
@@ -6227,7 +6176,7 @@ ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
QualifiedTemplateName *QTN =
QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
if (!QTN) {
@@ -6250,7 +6199,7 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Name);
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
DependentTemplateName *QTN =
DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
@@ -6285,8 +6234,8 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
llvm::FoldingSetNodeID ID;
DependentTemplateName::Profile(ID, NNS, Operator);
-
- void *InsertPos = 0;
+
+ void *InsertPos = nullptr;
DependentTemplateName *QTN
= DependentTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
@@ -6317,8 +6266,8 @@ ASTContext::getSubstTemplateTemplateParm(TemplateTemplateParmDecl *param,
TemplateName replacement) const {
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmStorage::Profile(ID, param, replacement);
-
- void *insertPos = 0;
+
+ void *insertPos = nullptr;
SubstTemplateTemplateParmStorage *subst
= SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
@@ -6336,8 +6285,8 @@ ASTContext::getSubstTemplateTemplateParmPack(TemplateTemplateParmDecl *Param,
ASTContext &Self = const_cast<ASTContext &>(*this);
llvm::FoldingSetNodeID ID;
SubstTemplateTemplateParmPackStorage::Profile(ID, Self, Param, ArgPack);
-
- void *InsertPos = 0;
+
+ void *InsertPos = nullptr;
SubstTemplateTemplateParmPackStorage *Subst
= SubstTemplateTemplateParmPacks.FindNodeOrInsertPos(ID, InsertPos);
@@ -6454,9 +6403,8 @@ ASTContext::ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const {
if (declaresSameEntity(lProto, rProto))
return true;
- for (ObjCProtocolDecl::protocol_iterator PI = rProto->protocol_begin(),
- E = rProto->protocol_end(); PI != E; ++PI)
- if (ProtocolCompatibleWithProtocol(lProto, *PI))
+ for (auto *PI : rProto->protocols())
+ if (ProtocolCompatibleWithProtocol(lProto, PI))
return true;
return false;
}
@@ -6469,13 +6417,9 @@ bool ASTContext::ObjCQualifiedClassTypesAreCompatible(QualType lhs,
const ObjCObjectPointerType *rhsOPT = rhs->getAs<ObjCObjectPointerType>();
assert ((lhsQID && rhsOPT) && "ObjCQualifiedClassTypesAreCompatible");
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
- ObjCProtocolDecl *lhsProto = *I;
- for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
- E = rhsOPT->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsOPT->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto)) {
match = true;
break;
@@ -6508,12 +6452,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// If the RHS is a unqualified interface pointer "NSString*",
// make sure we check the class hierarchy.
if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *I : lhsQID->quals()) {
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- if (!rhsID->ClassImplementsProtocol(*I, true))
+ if (!rhsID->ClassImplementsProtocol(I, true))
return false;
}
}
@@ -6521,17 +6464,13 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
return true;
}
// Both the right and left sides have qualifiers.
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
- ObjCProtocolDecl *lhsProto = *I;
+ for (auto *lhsProto : lhsQID->quals()) {
bool match = false;
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- for (ObjCObjectPointerType::qual_iterator J = rhsOPT->qual_begin(),
- E = rhsOPT->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsOPT->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6541,12 +6480,11 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// If the RHS is a qualified interface pointer "NSString<P>*",
// make sure we check the class hierarchy.
if (ObjCInterfaceDecl *rhsID = rhsOPT->getInterfaceDecl()) {
- for (ObjCObjectPointerType::qual_iterator I = lhsQID->qual_begin(),
- E = lhsQID->qual_end(); I != E; ++I) {
+ for (auto *I : lhsQID->quals()) {
// when comparing an id<P> on lhs with a static type on rhs,
// see if static class implements all of id's protocols, directly or
// through its super class and categories.
- if (rhsID->ClassImplementsProtocol(*I, true)) {
+ if (rhsID->ClassImplementsProtocol(I, true)) {
match = true;
break;
}
@@ -6565,9 +6503,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
if (const ObjCObjectPointerType *lhsOPT =
lhs->getAsObjCInterfacePointerType()) {
// If both the right and left sides have qualifiers.
- for (ObjCObjectPointerType::qual_iterator I = lhsOPT->qual_begin(),
- E = lhsOPT->qual_end(); I != E; ++I) {
- ObjCProtocolDecl *lhsProto = *I;
+ for (auto *lhsProto : lhsOPT->quals()) {
bool match = false;
// when comparing an id<P> on rhs with a static type on lhs,
@@ -6575,9 +6511,7 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// through its super class and categories.
// First, lhs protocols in the qualifier list must be found, direct
// or indirect in rhs's qualifier list or it is a mismatch.
- for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
- E = rhsQID->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsQID->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6598,14 +6532,9 @@ bool ASTContext::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
// assume that it is mismatch.
if (LHSInheritedProtocols.empty() && lhsOPT->qual_empty())
return false;
- for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
- LHSInheritedProtocols.begin(),
- E = LHSInheritedProtocols.end(); I != E; ++I) {
+ for (auto *lhsProto : LHSInheritedProtocols) {
bool match = false;
- ObjCProtocolDecl *lhsProto = (*I);
- for (ObjCObjectPointerType::qual_iterator J = rhsQID->qual_begin(),
- E = rhsQID->qual_end(); J != E; ++J) {
- ObjCProtocolDecl *rhsProto = *J;
+ for (auto *rhsProto : rhsQID->quals()) {
if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
(compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
match = true;
@@ -6798,16 +6727,9 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
if (SuperClassInheritedProtocols.empty())
return false;
- for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
- LHSPE = LHS->qual_end();
- LHSPI != LHSPE; LHSPI++) {
- bool SuperImplementsProtocol = false;
- ObjCProtocolDecl *LHSProto = (*LHSPI);
-
- for (llvm::SmallPtrSet<ObjCProtocolDecl*,8>::iterator I =
- SuperClassInheritedProtocols.begin(),
- E = SuperClassInheritedProtocols.end(); I != E; ++I) {
- ObjCProtocolDecl *SuperClassProto = (*I);
+ for (const auto *LHSProto : LHS->quals()) {
+ bool SuperImplementsProtocol = false;
+ for (auto *SuperClassProto : SuperClassInheritedProtocols) {
if (SuperClassProto->lookupProtocolNamed(LHSProto->getIdentifier())) {
SuperImplementsProtocol = true;
break;
@@ -6821,17 +6743,13 @@ bool ASTContext::canAssignObjCInterfaces(const ObjCObjectType *LHS,
return false;
}
- for (ObjCObjectType::qual_iterator LHSPI = LHS->qual_begin(),
- LHSPE = LHS->qual_end();
- LHSPI != LHSPE; LHSPI++) {
+ for (const auto *LHSPI : LHS->quals()) {
bool RHSImplementsProtocol = false;
// If the RHS doesn't implement the protocol on the left, the types
// are incompatible.
- for (ObjCObjectType::qual_iterator RHSPI = RHS->qual_begin(),
- RHSPE = RHS->qual_end();
- RHSPI != RHSPE; RHSPI++) {
- if ((*RHSPI)->lookupProtocolNamed((*LHSPI)->getIdentifier())) {
+ for (auto *RHSPI : RHS->quals()) {
+ if (RHSPI->lookupProtocolNamed(LHSPI->getIdentifier())) {
RHSImplementsProtocol = true;
break;
}
@@ -6891,9 +6809,8 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
if (const RecordType *UT = T->getAsUnionType()) {
RecordDecl *UD = UT->getDecl();
if (UD->hasAttr<TransparentUnionAttr>()) {
- for (RecordDecl::field_iterator it = UD->field_begin(),
- itend = UD->field_end(); it != itend; ++it) {
- QualType ET = it->getType().getUnqualifiedType();
+ for (const auto *I : UD->fields()) {
+ QualType ET = I->getType().getUnqualifiedType();
QualType MT = mergeTypes(ET, SubType, OfBlockPointer, Unqualified);
if (!MT.isNull())
return MT;
@@ -6904,11 +6821,11 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
return QualType();
}
-/// mergeFunctionArgumentTypes - merge two types which appear as function
-/// argument types
-QualType ASTContext::mergeFunctionArgumentTypes(QualType lhs, QualType rhs,
- bool OfBlockPointer,
- bool Unqualified) {
+/// mergeFunctionParameterTypes - merge two types which appear as function
+/// parameter types
+QualType ASTContext::mergeFunctionParameterTypes(QualType lhs, QualType rhs,
+ bool OfBlockPointer,
+ bool Unqualified) {
// GNU extension: two types are compatible if they appear as a function
// argument, one of the types is a transparent union type and the other
// type is compatible with a union member
@@ -6938,23 +6855,23 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Check return type
QualType retType;
if (OfBlockPointer) {
- QualType RHS = rbase->getResultType();
- QualType LHS = lbase->getResultType();
+ QualType RHS = rbase->getReturnType();
+ QualType LHS = lbase->getReturnType();
bool UnqualifiedResult = Unqualified;
if (!UnqualifiedResult)
UnqualifiedResult = (!RHS.hasQualifiers() && LHS.hasQualifiers());
retType = mergeTypes(LHS, RHS, true, UnqualifiedResult, true);
}
else
- retType = mergeTypes(lbase->getResultType(), rbase->getResultType(), false,
+ retType = mergeTypes(lbase->getReturnType(), rbase->getReturnType(), false,
Unqualified);
if (retType.isNull()) return QualType();
if (Unqualified)
retType = retType.getUnqualifiedType();
- CanQualType LRetType = getCanonicalType(lbase->getResultType());
- CanQualType RRetType = getCanonicalType(rbase->getResultType());
+ CanQualType LRetType = getCanonicalType(lbase->getReturnType());
+ CanQualType RRetType = getCanonicalType(rbase->getReturnType());
if (Unqualified) {
LRetType = LRetType.getUnqualifiedType();
RRetType = RRetType.getUnqualifiedType();
@@ -6998,11 +6915,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (lproto && rproto) { // two C99 style function prototypes
assert(!lproto->hasExceptionSpec() && !rproto->hasExceptionSpec() &&
"C++ shouldn't be here");
- unsigned lproto_nargs = lproto->getNumArgs();
- unsigned rproto_nargs = rproto->getNumArgs();
-
- // Compatible functions must have the same number of arguments
- if (lproto_nargs != rproto_nargs)
+ // Compatible functions must have the same number of parameters
+ if (lproto->getNumParams() != rproto->getNumParams())
return QualType();
// Variadic and non-variadic functions aren't compatible
@@ -7015,29 +6929,29 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
if (LangOpts.ObjCAutoRefCount &&
!FunctionTypesMatchOnNSConsumedAttrs(rproto, lproto))
return QualType();
-
- // Check argument compatibility
+
+ // Check parameter type compatibility
SmallVector<QualType, 10> types;
- for (unsigned i = 0; i < lproto_nargs; i++) {
- QualType largtype = lproto->getArgType(i).getUnqualifiedType();
- QualType rargtype = rproto->getArgType(i).getUnqualifiedType();
- QualType argtype = mergeFunctionArgumentTypes(largtype, rargtype,
- OfBlockPointer,
- Unqualified);
- if (argtype.isNull()) return QualType();
-
+ for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) {
+ QualType lParamType = lproto->getParamType(i).getUnqualifiedType();
+ QualType rParamType = rproto->getParamType(i).getUnqualifiedType();
+ QualType paramType = mergeFunctionParameterTypes(
+ lParamType, rParamType, OfBlockPointer, Unqualified);
+ if (paramType.isNull())
+ return QualType();
+
if (Unqualified)
- argtype = argtype.getUnqualifiedType();
-
- types.push_back(argtype);
+ paramType = paramType.getUnqualifiedType();
+
+ types.push_back(paramType);
if (Unqualified) {
- largtype = largtype.getUnqualifiedType();
- rargtype = rargtype.getUnqualifiedType();
+ lParamType = lParamType.getUnqualifiedType();
+ rParamType = rParamType.getUnqualifiedType();
}
-
- if (getCanonicalType(argtype) != getCanonicalType(largtype))
+
+ if (getCanonicalType(paramType) != getCanonicalType(lParamType))
allLTypes = false;
- if (getCanonicalType(argtype) != getCanonicalType(rargtype))
+ if (getCanonicalType(paramType) != getCanonicalType(rParamType))
allRTypes = false;
}
@@ -7061,20 +6975,19 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// The only types actually affected are promotable integer
// types and floats, which would be passed as a different
// type depending on whether the prototype is visible.
- unsigned proto_nargs = proto->getNumArgs();
- for (unsigned i = 0; i < proto_nargs; ++i) {
- QualType argTy = proto->getArgType(i);
-
+ for (unsigned i = 0, n = proto->getNumParams(); i < n; ++i) {
+ QualType paramTy = proto->getParamType(i);
+
// Look at the converted type of enum types, since that is the type used
// to pass enum values.
- if (const EnumType *Enum = argTy->getAs<EnumType>()) {
- argTy = Enum->getDecl()->getIntegerType();
- if (argTy.isNull())
+ if (const EnumType *Enum = paramTy->getAs<EnumType>()) {
+ paramTy = Enum->getDecl()->getIntegerType();
+ if (paramTy.isNull())
return QualType();
}
-
- if (argTy->isPromotableIntegerType() ||
- getCanonicalType(argTy).getUnqualifiedType() == FloatTy)
+
+ if (paramTy->isPromotableIntegerType() ||
+ getCanonicalType(paramTy).getUnqualifiedType() == FloatTy)
return QualType();
}
@@ -7083,7 +6996,7 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
FunctionProtoType::ExtProtoInfo EPI = proto->getExtProtoInfo();
EPI.ExtInfo = einfo;
- return getFunctionType(retType, proto->getArgTypes(), EPI);
+ return getFunctionType(retType, proto->getParamTypes(), EPI);
}
if (allLTypes) return lhs;
@@ -7387,18 +7300,16 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
bool ASTContext::FunctionTypesMatchOnNSConsumedAttrs(
const FunctionProtoType *FromFunctionType,
const FunctionProtoType *ToFunctionType) {
- if (FromFunctionType->hasAnyConsumedArgs() !=
- ToFunctionType->hasAnyConsumedArgs())
+ if (FromFunctionType->hasAnyConsumedParams() !=
+ ToFunctionType->hasAnyConsumedParams())
return false;
FunctionProtoType::ExtProtoInfo FromEPI =
FromFunctionType->getExtProtoInfo();
FunctionProtoType::ExtProtoInfo ToEPI =
ToFunctionType->getExtProtoInfo();
- if (FromEPI.ConsumedArguments && ToEPI.ConsumedArguments)
- for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
- ArgIdx != NumArgs; ++ArgIdx) {
- if (FromEPI.ConsumedArguments[ArgIdx] !=
- ToEPI.ConsumedArguments[ArgIdx])
+ if (FromEPI.ConsumedParameters && ToEPI.ConsumedParameters)
+ for (unsigned i = 0, n = FromFunctionType->getNumParams(); i != n; ++i) {
+ if (FromEPI.ConsumedParameters[i] != ToEPI.ConsumedParameters[i])
return false;
}
return true;
@@ -7416,10 +7327,10 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
if (RHSCan->isFunctionType()) {
if (!LHSCan->isFunctionType())
return QualType();
- QualType OldReturnType =
- cast<FunctionType>(RHSCan.getTypePtr())->getResultType();
+ QualType OldReturnType =
+ cast<FunctionType>(RHSCan.getTypePtr())->getReturnType();
QualType NewReturnType =
- cast<FunctionType>(LHSCan.getTypePtr())->getResultType();
+ cast<FunctionType>(LHSCan.getTypePtr())->getReturnType();
QualType ResReturnType =
mergeObjCGCQualifiers(NewReturnType, OldReturnType);
if (ResReturnType.isNull())
@@ -7432,7 +7343,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
EPI.ExtInfo = getFunctionExtInfo(LHS);
QualType ResultType =
- getFunctionType(OldReturnType, FPT->getArgTypes(), EPI);
+ getFunctionType(OldReturnType, FPT->getParamTypes(), EPI);
return ResultType;
}
}
@@ -7573,6 +7484,19 @@ static QualType DecodeTypeFromStr(const char *&Str, const ASTContext &Context,
assert(HowLong <= 2 && "Can't have LLLL modifier");
++HowLong;
break;
+ case 'W':
+ // This modifier represents int64 type.
+ assert(HowLong == 0 && "Can't use both 'L' and 'W' modifiers!");
+ switch (Context.getTargetInfo().getInt64Type()) {
+ default:
+ llvm_unreachable("Unexpected integer type");
+ case TargetInfo::SignedLong:
+ HowLong = 1;
+ break;
+ case TargetInfo::SignedLongLong:
+ HowLong = 2;
+ break;
+ }
}
}
@@ -7834,7 +7758,8 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
return getFunctionType(ResType, ArgTypes, EPI);
}
-GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
+static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
+ const FunctionDecl *FD) {
if (!FD->isExternallyVisible())
return GVA_Internal;
@@ -7846,68 +7771,126 @@ GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) {
break;
case TSK_ExplicitInstantiationDefinition:
- return GVA_ExplicitTemplateInstantiation;
+ return GVA_StrongODR;
+ // C++11 [temp.explicit]p10:
+ // [ Note: The intent is that an inline function that is the subject of
+ // an explicit instantiation declaration will still be implicitly
+ // instantiated when used so that the body can be considered for
+ // inlining, but that no out-of-line copy of the inline function would be
+ // generated in the translation unit. -- end note ]
case TSK_ExplicitInstantiationDeclaration:
+ return GVA_AvailableExternally;
+
case TSK_ImplicitInstantiation:
- External = GVA_TemplateInstantiation;
+ External = GVA_DiscardableODR;
break;
}
if (!FD->isInlined())
return External;
- if ((!getLangOpts().CPlusPlus && !getLangOpts().MicrosoftMode) ||
+ if ((!Context.getLangOpts().CPlusPlus && !Context.getLangOpts().MSVCCompat &&
+ !FD->hasAttr<DLLExportAttr>()) ||
FD->hasAttr<GNUInlineAttr>()) {
+ // FIXME: This doesn't match gcc's behavior for dllexport inline functions.
+
// GNU or C99 inline semantics. Determine whether this symbol should be
// externally visible.
if (FD->isInlineDefinitionExternallyVisible())
return External;
// C99 inline semantics, where the symbol is not externally visible.
- return GVA_C99Inline;
+ return GVA_AvailableExternally;
}
- // C++0x [temp.explicit]p9:
- // [ Note: The intent is that an inline function that is the subject of
- // an explicit instantiation declaration will still be implicitly
- // instantiated when used so that the body can be considered for
- // inlining, but that no out-of-line copy of the inline function would be
- // generated in the translation unit. -- end note ]
- if (FD->getTemplateSpecializationKind()
- == TSK_ExplicitInstantiationDeclaration)
- return GVA_C99Inline;
+ // Functions specified with extern and inline in -fms-compatibility mode
+ // forcibly get emitted. While the body of the function cannot be later
+ // replaced, the function definition cannot be discarded.
+ if (FD->getMostRecentDecl()->isMSExternInline())
+ return GVA_StrongODR;
- return GVA_CXXInline;
+ return GVA_DiscardableODR;
}
-GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+static GVALinkage adjustGVALinkageForDLLAttribute(GVALinkage L, const Decl *D) {
+ // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
+ // dllexport/dllimport on inline functions.
+ if (D->hasAttr<DLLImportAttr>()) {
+ if (L == GVA_DiscardableODR || L == GVA_StrongODR)
+ return GVA_AvailableExternally;
+ } else if (D->hasAttr<DLLExportAttr>()) {
+ if (L == GVA_DiscardableODR)
+ return GVA_StrongODR;
+ }
+ return L;
+}
+
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
+ return adjustGVALinkageForDLLAttribute(basicGVALinkageForFunction(*this, FD),
+ FD);
+}
+
+static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
+ const VarDecl *VD) {
if (!VD->isExternallyVisible())
return GVA_Internal;
+ if (VD->isStaticLocal()) {
+ GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
+ const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
+ while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
+ LexicalContext = LexicalContext->getLexicalParent();
+
+ // Let the static local variable inherit it's linkage from the nearest
+ // enclosing function.
+ if (LexicalContext)
+ StaticLocalLinkage =
+ Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+ // GVA_StrongODR function linkage is stronger than what we need,
+ // downgrade to GVA_DiscardableODR.
+ // This allows us to discard the variable if we never end up needing it.
+ return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
+ : StaticLocalLinkage;
+ }
+
+ // MSVC treats in-class initialized static data members as definitions.
+ // By giving them non-strong linkage, out-of-line definitions won't
+ // cause link errors.
+ if (Context.isMSStaticDataMemberInlineDefinition(VD))
+ return GVA_DiscardableODR;
+
switch (VD->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
return GVA_StrongExternal;
- case TSK_ExplicitInstantiationDeclaration:
- llvm_unreachable("Variable should not be instantiated");
- // Fall through to treat this like any other instantiation.
-
case TSK_ExplicitInstantiationDefinition:
- return GVA_ExplicitTemplateInstantiation;
+ return GVA_StrongODR;
+
+ case TSK_ExplicitInstantiationDeclaration:
+ return GVA_AvailableExternally;
case TSK_ImplicitInstantiation:
- return GVA_TemplateInstantiation;
+ return GVA_DiscardableODR;
}
llvm_unreachable("Invalid Linkage!");
}
+GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
+ return adjustGVALinkageForDLLAttribute(basicGVALinkageForVariable(*this, VD),
+ VD);
+}
+
bool ASTContext::DeclMustBeEmitted(const Decl *D) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
if (!VD->isFileVarDecl())
return false;
+ // Global named register variables (GNU extension) are never emitted.
+ if (VD->getStorageClass() == SC_Register)
+ return false;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
// We never need to emit an uninstantiated function template.
if (FD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
@@ -7954,8 +7937,8 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
// static, static inline, always_inline, and extern inline functions can
// always be deferred. Normal inline functions can be deferred in C99/C++.
// Implicit template instantiations can also be deferred in C++.
- if (Linkage == GVA_Internal || Linkage == GVA_C99Inline ||
- Linkage == GVA_CXXInline || Linkage == GVA_TemplateInstantiation)
+ if (Linkage == GVA_Internal || Linkage == GVA_AvailableExternally ||
+ Linkage == GVA_DiscardableODR)
return false;
return true;
}
@@ -7963,12 +7946,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
const VarDecl *VD = cast<VarDecl>(D);
assert(VD->isFileVarDecl() && "Expected file scoped var");
- if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
+ if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly &&
+ !isMSStaticDataMemberInlineDefinition(VD))
return false;
// Variables that can be needed in other TUs are required.
GVALinkage L = GetGVALinkageForVariable(VD);
- if (L != GVA_Internal && L != GVA_TemplateInstantiation)
+ if (L != GVA_Internal && L != GVA_AvailableExternally &&
+ L != GVA_DiscardableODR)
return true;
// Variables that have destruction with side-effects are required.
@@ -7996,12 +7981,23 @@ bool ASTContext::isNearlyEmpty(const CXXRecordDecl *RD) const {
return ABI->isNearlyEmpty(RD);
}
+VTableContextBase *ASTContext::getVTableContext() {
+ if (!VTContext.get()) {
+ if (Target->getCXXABI().isMicrosoft())
+ VTContext.reset(new MicrosoftVTableContext(*this));
+ else
+ VTContext.reset(new ItaniumVTableContext(*this));
+ }
+ return VTContext.get();
+}
+
MangleContext *ASTContext::createMangleContext() {
switch (Target->getCXXABI().getKind()) {
case TargetCXXABI::GenericAArch64:
case TargetCXXABI::GenericItanium:
case TargetCXXABI::GenericARM:
case TargetCXXABI::iOS:
+ case TargetCXXABI::iOS64:
return ItaniumMangleContext::create(*this, getDiagnostics());
case TargetCXXABI::Microsoft:
return MicrosoftMangleContext::create(*this, getDiagnostics());
@@ -8071,6 +8067,17 @@ unsigned ASTContext::getManglingNumber(const NamedDecl *ND) const {
return I != MangleNumbers.end() ? I->second : 1;
}
+void ASTContext::setStaticLocalNumber(const VarDecl *VD, unsigned Number) {
+ if (Number > 1)
+ StaticLocalNumbers[VD] = Number;
+}
+
+unsigned ASTContext::getStaticLocalNumber(const VarDecl *VD) const {
+ llvm::DenseMap<const VarDecl *, unsigned>::const_iterator I =
+ StaticLocalNumbers.find(VD);
+ return I != StaticLocalNumbers.end() ? I->second : 1;
+}
+
MangleNumberingContext &
ASTContext::getManglingNumberContext(const DeclContext *DC) {
assert(LangOpts.CPlusPlus); // We don't need mangling numbers for plain C.
@@ -8105,7 +8112,7 @@ ASTContext::getMaterializedTemporaryValue(const MaterializeTemporaryExpr *E,
llvm::DenseMap<const MaterializeTemporaryExpr *, APValue>::iterator I =
MaterializedTemporaryValues.find(E);
- return I == MaterializedTemporaryValues.end() ? 0 : &I->second;
+ return I == MaterializedTemporaryValues.end() ? nullptr : &I->second;
}
bool ASTContext::AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const {
@@ -8168,18 +8175,45 @@ namespace {
template <typename T>
bool TraverseNode(T *Node, bool(VisitorBase:: *traverse) (T *)) {
- if (Node == NULL)
+ if (!Node)
return true;
- if (ParentStack.size() > 0)
- // FIXME: Currently we add the same parent multiple times, for example
- // when we visit all subexpressions of template instantiations; this is
- // suboptimal, bug benign: the only way to visit those is with
- // hasAncestor / hasParent, and those do not create new matches.
+ if (ParentStack.size() > 0) {
+ // FIXME: Currently we add the same parent multiple times, but only
+ // when no memoization data is available for the type.
+ // For example when we visit all subexpressions of template
+ // instantiations; this is suboptimal, but benign: the only way to
+ // visit those is with hasAncestor / hasParent, and those do not create
+ // new matches.
// The plan is to enable DynTypedNode to be storable in a map or hash
// map. The main problem there is to implement hash functions /
// comparison operators for all types that DynTypedNode supports that
// do not have pointer identity.
- (*Parents)[Node].push_back(ParentStack.back());
+ auto &NodeOrVector = (*Parents)[Node];
+ if (NodeOrVector.isNull()) {
+ NodeOrVector = new ast_type_traits::DynTypedNode(ParentStack.back());
+ } else {
+ if (NodeOrVector.template is<ast_type_traits::DynTypedNode *>()) {
+ auto *Node =
+ NodeOrVector.template get<ast_type_traits::DynTypedNode *>();
+ auto *Vector = new ASTContext::ParentVector(1, *Node);
+ NodeOrVector = Vector;
+ delete Node;
+ }
+ assert(NodeOrVector.template is<ASTContext::ParentVector *>());
+
+ auto *Vector =
+ NodeOrVector.template get<ASTContext::ParentVector *>();
+ // Skip duplicates for types that have memoization data.
+ // We must check that the type has memoization data before calling
+ // std::find() because DynTypedNode::operator== can't compare all
+ // types.
+ bool Found = ParentStack.back().getMemoizationData() &&
+ std::find(Vector->begin(), Vector->end(),
+ ParentStack.back()) != Vector->end();
+ if (!Found)
+ Vector->push_back(ParentStack.back());
+ }
+ }
ParentStack.push_back(ast_type_traits::DynTypedNode::create(*Node));
bool Result = (this ->* traverse) (Node);
ParentStack.pop_back();
@@ -8217,7 +8251,11 @@ ASTContext::getParents(const ast_type_traits::DynTypedNode &Node) {
if (I == AllParents->end()) {
return ParentVector();
}
- return I->second;
+ if (I->second.is<ast_type_traits::DynTypedNode *>()) {
+ return ParentVector(1, *I->second.get<ast_type_traits::DynTypedNode *>());
+ }
+ const auto &Parents = *I->second.get<ParentVector *>();
+ return ParentVector(Parents.begin(), Parents.end());
}
bool
@@ -8230,8 +8268,7 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
if (MethodDecl->getObjCDeclQualifier() !=
MethodImpl->getObjCDeclQualifier())
return false;
- if (!hasSameType(MethodDecl->getResultType(),
- MethodImpl->getResultType()))
+ if (!hasSameType(MethodDecl->getReturnType(), MethodImpl->getReturnType()))
return false;
if (MethodDecl->param_size() != MethodImpl->param_size())
@@ -8251,3 +8288,12 @@ ASTContext::ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl,
return (MethodDecl->isVariadic() == MethodImpl->isVariadic());
}
+
+// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
+// doesn't include ASTContext.h
+template
+clang::LazyGenerationalUpdatePtr<
+ const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::ValueType
+clang::LazyGenerationalUpdatePtr<
+ const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
+ const clang::ASTContext &Ctx, Decl *Value);
diff --git a/lib/AST/ASTDiagnostic.cpp b/lib/AST/ASTDiagnostic.cpp
index fce8f64b3328..8c8b1dff0cbf 100644
--- a/lib/AST/ASTDiagnostic.cpp
+++ b/lib/AST/ASTDiagnostic.cpp
@@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTDiagnostic.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
@@ -51,6 +53,11 @@ static QualType Desugar(ASTContext &Context, QualType QT, bool &ShouldAKA) {
QT = AT->desugar();
continue;
}
+ // ...or an adjusted type...
+ if (const AdjustedType *AT = dyn_cast<AdjustedType>(Ty)) {
+ QT = AT->desugar();
+ continue;
+ }
// ... or an auto type.
if (const AutoType *AT = dyn_cast<AutoType>(Ty)) {
if (!AT->isSugared())
@@ -155,9 +162,8 @@ break; \
/// diagnostic message
static std::string
ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
- ArrayRef<intptr_t> QualTypeVals) {
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+ ArrayRef<intptr_t> QualTypeVals) {
// FIXME: Playing with std::string is really slow.
bool ForceAKA = false;
QualType CanTy = Ty.getCanonicalType();
@@ -195,7 +201,7 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
// Check to see if we already desugared this type in this
// diagnostic. If so, don't do it again.
bool Repeated = false;
- for (unsigned i = 0; i != NumPrevArgs; ++i) {
+ for (unsigned i = 0, e = PrevArgs.size(); i != e; ++i) {
// TODO: Handle ak_declcontext case.
if (PrevArgs[i].first == DiagnosticsEngine::ak_qualtype) {
void *Ptr = (void*)PrevArgs[i].second;
@@ -222,6 +228,20 @@ ConvertTypeToDiagnosticString(ASTContext &Context, QualType Ty,
return S;
}
}
+
+ // Give some additional info on vector types. These are either not desugared
+ // or displaying complex __attribute__ expressions so add details of the
+ // type and element count.
+ if (Ty->isVectorType()) {
+ const VectorType *VTy = Ty->getAs<VectorType>();
+ std::string DecoratedString;
+ llvm::raw_string_ostream OS(DecoratedString);
+ const char *Values = VTy->getNumElements() > 1 ? "values" : "value";
+ OS << "'" << S << "' (vector of " << VTy->getNumElements() << " '"
+ << VTy->getElementType().getAsString(Context.getPrintingPolicy())
+ << "' " << Values << ")";
+ return OS.str();
+ }
}
S = "'" + S + "'";
@@ -236,12 +256,9 @@ static bool FormatTemplateTypeDiff(ASTContext &Context, QualType FromType,
void clang::FormatASTNodeDiagnosticArgument(
DiagnosticsEngine::ArgumentKind Kind,
intptr_t Val,
- const char *Modifier,
- unsigned ModLen,
- const char *Argument,
- unsigned ArgLen,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
+ StringRef Modifier,
+ StringRef Argument,
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
SmallVectorImpl<char> &Output,
void *Cookie,
ArrayRef<intptr_t> QualTypeVals) {
@@ -276,28 +293,26 @@ void clang::FormatASTNodeDiagnosticArgument(
// Attempting to do a template diff on non-templates. Set the variables
// and continue with regular type printing of the appropriate type.
Val = TDT.PrintFromType ? TDT.FromType : TDT.ToType;
- ModLen = 0;
- ArgLen = 0;
+ Modifier = StringRef();
+ Argument = StringRef();
// Fall through
}
case DiagnosticsEngine::ak_qualtype: {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for QualType argument");
QualType Ty(QualType::getFromOpaquePtr(reinterpret_cast<void*>(Val)));
- OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, NumPrevArgs,
- QualTypeVals);
+ OS << ConvertTypeToDiagnosticString(Context, Ty, PrevArgs, QualTypeVals);
NeedQuotes = false;
break;
}
case DiagnosticsEngine::ak_declarationname: {
- if (ModLen == 9 && !memcmp(Modifier, "objcclass", 9) && ArgLen == 0)
+ if (Modifier == "objcclass" && Argument.empty())
OS << '+';
- else if (ModLen == 12 && !memcmp(Modifier, "objcinstance", 12)
- && ArgLen==0)
+ else if (Modifier == "objcinstance" && Argument.empty())
OS << '-';
else
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for DeclarationName argument");
OS << DeclarationName::getFromOpaqueInteger(Val);
@@ -305,10 +320,10 @@ void clang::FormatASTNodeDiagnosticArgument(
}
case DiagnosticsEngine::ak_nameddecl: {
bool Qualified;
- if (ModLen == 1 && Modifier[0] == 'q' && ArgLen == 0)
+ if (Modifier == "q" && Argument.empty())
Qualified = true;
else {
- assert(ModLen == 0 && ArgLen == 0 &&
+ assert(Modifier.empty() && Argument.empty() &&
"Invalid modifier for NamedDecl* argument");
Qualified = false;
}
@@ -325,7 +340,8 @@ void clang::FormatASTNodeDiagnosticArgument(
case DiagnosticsEngine::ak_declcontext: {
DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
assert(DC && "Should never have a null declaration context");
-
+ NeedQuotes = false;
+
if (DC->isTranslationUnit()) {
// FIXME: Get these strings from some localized place
if (Context.getLangOpts().CPlusPlus)
@@ -335,10 +351,17 @@ void clang::FormatASTNodeDiagnosticArgument(
} else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
OS << ConvertTypeToDiagnosticString(Context,
Context.getTypeDeclType(Type),
- PrevArgs, NumPrevArgs,
- QualTypeVals);
+ PrevArgs, QualTypeVals);
} else {
// FIXME: Get these strings from some localized place
+ if (isa<BlockDecl>(DC)) {
+ OS << "block literal";
+ break;
+ }
+ if (isLambdaCallOperator(DC)) {
+ OS << "lambda expression";
+ break;
+ }
NamedDecl *ND = cast<NamedDecl>(DC);
if (isa<NamespaceDecl>(ND))
OS << "namespace ";
@@ -351,9 +374,16 @@ void clang::FormatASTNodeDiagnosticArgument(
ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), true);
OS << '\'';
}
+ break;
+ }
+ case DiagnosticsEngine::ak_attr: {
+ const Attr *At = reinterpret_cast<Attr *>(Val);
+ assert(At && "Received null Attr object!");
+ OS << '\'' << At->getSpelling() << '\'';
NeedQuotes = false;
break;
}
+
}
OS.flush();
@@ -442,6 +472,9 @@ class TemplateDiff {
/// FromExpr, ToExpr - The expression arguments.
Expr *FromExpr, *ToExpr;
+ /// FromNullPtr, ToNullPtr - If the template argument is a nullptr
+ bool FromNullPtr, ToNullPtr;
+
/// FromTD, ToTD - The template decl for template template
/// arguments or the type arguments that are templates.
TemplateDecl *FromTD, *ToTD;
@@ -470,10 +503,12 @@ class TemplateDiff {
DiffNode(unsigned ParentNode = 0)
: Kind(Invalid), NextNode(0), ChildNode(0), ParentNode(ParentNode),
- FromType(), ToType(), FromExpr(0), ToExpr(0), FromTD(0), ToTD(0),
- IsValidFromInt(false), IsValidToInt(false), FromValueDecl(0),
- ToValueDecl(0), FromAddressOf(false), ToAddressOf(false),
- FromDefault(false), ToDefault(false), Same(false) { }
+ FromType(), ToType(), FromExpr(nullptr), ToExpr(nullptr),
+ FromNullPtr(false), ToNullPtr(false),
+ FromTD(nullptr), ToTD(nullptr), IsValidFromInt(false),
+ IsValidToInt(false), FromValueDecl(nullptr), ToValueDecl(nullptr),
+ FromAddressOf(false), ToAddressOf(false), FromDefault(false),
+ ToDefault(false), Same(false) {}
};
/// FlatTree - A flattened tree used to store the DiffNodes.
@@ -543,6 +578,12 @@ class TemplateDiff {
FlatTree[CurrentNode].Same = Same;
}
+ /// SetNullPtr - Sets the NullPtr flags of the current node.
+ void SetNullPtr(bool FromNullPtr, bool ToNullPtr) {
+ FlatTree[CurrentNode].FromNullPtr = FromNullPtr;
+ FlatTree[CurrentNode].ToNullPtr = ToNullPtr;
+ }
+
/// SetDefault - Sets FromDefault and ToDefault flags of the current node.
void SetDefault(bool FromDefault, bool ToDefault) {
FlatTree[CurrentNode].FromDefault = FromDefault;
@@ -665,6 +706,16 @@ class TemplateDiff {
return FlatTree[ReadNode].NextNode != 0;
}
+ /// FromNullPtr - Returns true if the from argument is null.
+ bool FromNullPtr() {
+ return FlatTree[ReadNode].FromNullPtr;
+ }
+
+ /// ToNullPtr - Returns true if the to argument is null.
+ bool ToNullPtr() {
+ return FlatTree[ReadNode].ToNullPtr;
+ }
+
/// FromDefault - Return true if the from argument is the default.
bool FromDefault() {
return FlatTree[ReadNode].FromDefault;
@@ -718,7 +769,7 @@ class TemplateDiff {
TSTiterator(ASTContext &Context, const TemplateSpecializationType *TST)
: TST(TST),
DesugarTST(GetTemplateSpecializationType(Context, TST->desugar())),
- Index(0), CurrentTA(0), EndTA(0) {
+ Index(0), CurrentTA(nullptr), EndTA(nullptr) {
if (isEnd()) return;
// Set to first template argument. If not a parameter pack, done.
@@ -809,13 +860,13 @@ class TemplateDiff {
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
- return 0;
+ return nullptr;
const ClassTemplateSpecializationDecl *CTSD =
dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
if (!CTSD)
- return 0;
+ return nullptr;
Ty = Context.getTemplateSpecializationType(
TemplateName(CTSD->getSpecializedTemplate()),
@@ -887,9 +938,9 @@ class TemplateDiff {
// Handle Expressions
if (NonTypeTemplateParmDecl *DefaultNTTPD =
dyn_cast<NonTypeTemplateParmDecl>(ParamND)) {
- Expr *FromExpr = 0, *ToExpr = 0;
+ Expr *FromExpr = nullptr, *ToExpr = nullptr;
llvm::APSInt FromInt, ToInt;
- ValueDecl *FromValueDecl = 0, *ToValueDecl = 0;
+ ValueDecl *FromValueDecl = nullptr, *ToValueDecl = nullptr;
unsigned ParamWidth = 128; // Safe default
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType())
ParamWidth = Context.getIntWidth(DefaultNTTPD->getType());
@@ -903,6 +954,10 @@ class TemplateDiff {
bool HasToValueDecl =
!ToIter.isEnd() &&
ToIter->getKind() == TemplateArgument::Declaration;
+ bool FromNullPtr = !FromIter.isEnd() &&
+ FromIter->getKind() == TemplateArgument::NullPtr;
+ bool ToNullPtr =
+ !ToIter.isEnd() && ToIter->getKind() == TemplateArgument::NullPtr;
assert(((!HasFromInt && !HasToInt) ||
(!HasFromValueDecl && !HasToValueDecl)) &&
@@ -912,41 +967,54 @@ class TemplateDiff {
FromInt = FromIter->getAsIntegral();
else if (HasFromValueDecl)
FromValueDecl = FromIter->getAsDecl();
- else
+ else if (!FromNullPtr)
FromExpr = GetExpr(FromIter, DefaultNTTPD);
if (HasToInt)
ToInt = ToIter->getAsIntegral();
else if (HasToValueDecl)
ToValueDecl = ToIter->getAsDecl();
- else
+ else if (!ToNullPtr)
ToExpr = GetExpr(ToIter, DefaultNTTPD);
+ bool TemplateArgumentIsPointerType =
+ DefaultNTTPD->getType()->isPointerType();
+ if (FromExpr && TemplateArgumentIsPointerType) {
+ FromNullPtr = CheckForNullPtr(FromExpr);
+ }
+ if (ToExpr && TemplateArgumentIsPointerType) {
+ ToNullPtr = CheckForNullPtr(ToExpr);
+ }
+
if (!HasFromInt && !HasToInt && !HasFromValueDecl && !HasToValueDecl) {
Tree.SetNode(FromExpr, ToExpr);
Tree.SetDefault(FromIter.isEnd() && FromExpr,
ToIter.isEnd() && ToExpr);
if (DefaultNTTPD->getType()->isIntegralOrEnumerationType()) {
if (FromExpr)
- FromInt = GetInt(FromIter, FromExpr);
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
if (ToExpr)
- ToInt = GetInt(ToIter, ToExpr);
- Tree.SetNode(FromInt, ToInt, FromExpr, ToExpr);
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
+ }
+ if (HasFromInt && HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetKind(DiffTree::Integer);
+ } else if (HasFromInt || HasToInt) {
+ Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
+ Tree.SetSame(false);
+ Tree.SetKind(DiffTree::Integer);
} else {
- Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr));
+ Tree.SetSame(IsEqualExpr(Context, ParamWidth, FromExpr, ToExpr) ||
+ (FromNullPtr && ToNullPtr));
+ Tree.SetNullPtr(FromNullPtr, ToNullPtr);
Tree.SetKind(DiffTree::Expression);
}
} else if (HasFromInt || HasToInt) {
- if (!HasFromInt && FromExpr) {
- FromInt = GetInt(FromIter, FromExpr);
- HasFromInt = true;
- }
- if (!HasToInt && ToExpr) {
- ToInt = GetInt(ToIter, ToExpr);
- HasToInt = true;
- }
+ if (!HasFromInt && FromExpr)
+ HasFromInt = GetInt(FromIter, FromExpr, FromInt);
+ if (!HasToInt && ToExpr)
+ HasToInt = GetInt(ToIter, ToExpr, ToInt);
Tree.SetNode(FromInt, ToInt, HasFromInt, HasToInt);
Tree.SetSame(IsSameConvertedInt(ParamWidth, FromInt, ToInt));
Tree.SetDefault(FromIter.isEnd() && HasFromInt,
@@ -958,12 +1026,36 @@ class TemplateDiff {
if (!HasToValueDecl && ToExpr)
ToValueDecl = GetValueDecl(ToIter, ToExpr);
QualType ArgumentType = DefaultNTTPD->getType();
- bool FromAddressOf = FromValueDecl &&
- !ArgumentType->isReferenceType() &&
- !FromValueDecl->getType()->isArrayType();
- bool ToAddressOf = ToValueDecl &&
- !ArgumentType->isReferenceType() &&
- !ToValueDecl->getType()->isArrayType();
+ bool FromAddressOf = false;
+ if (FromValueDecl) {
+ if (FromExpr) {
+ if (UnaryOperator *UO =
+ dyn_cast<UnaryOperator>(FromExpr->IgnoreParens())) {
+ if (UO->getOpcode() == UO_AddrOf)
+ FromAddressOf = true;
+ }
+ } else {
+ if (!ArgumentType->isReferenceType()) {
+ FromAddressOf = true;
+ }
+ }
+ }
+ bool ToAddressOf = false;
+ if (ToValueDecl) {
+ if (ToExpr) {
+ if (UnaryOperator *UO =
+ dyn_cast<UnaryOperator>(ToExpr->IgnoreParens())) {
+ if (UO->getOpcode() == UO_AddrOf) {
+ ToAddressOf = true;
+ }
+ }
+ } else {
+ if (!ArgumentType->isReferenceType()) {
+ ToAddressOf = true;
+ }
+ }
+ }
+ Tree.SetNullPtr(FromNullPtr, ToNullPtr);
Tree.SetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
Tree.SetSame(FromValueDecl && ToValueDecl &&
FromValueDecl->getCanonicalDecl() ==
@@ -984,6 +1076,7 @@ class TemplateDiff {
Tree.SetSame(
FromDecl && ToDecl &&
FromDecl->getCanonicalDecl() == ToDecl->getCanonicalDecl());
+ Tree.SetDefault(FromIter.isEnd() && FromDecl, ToIter.isEnd() && ToDecl);
Tree.SetKind(DiffTree::TemplateTemplate);
}
@@ -1072,7 +1165,7 @@ class TemplateDiff {
/// GetExpr - Retrieves the template expression argument, including default
/// arguments.
Expr *GetExpr(const TSTiterator &Iter, NonTypeTemplateParmDecl *DefaultNTTPD) {
- Expr *ArgExpr = 0;
+ Expr *ArgExpr = nullptr;
bool isVariadic = DefaultNTTPD->isParameterPack();
if (!Iter.isEnd())
@@ -1090,20 +1183,28 @@ class TemplateDiff {
/// GetInt - Retrieves the template integer argument, including evaluating
/// default arguments.
- llvm::APInt GetInt(const TSTiterator &Iter, Expr *ArgExpr) {
+ bool GetInt(const TSTiterator &Iter, Expr *ArgExpr, llvm::APInt &Int) {
// Default, value-depenedent expressions require fetching
- // from the desugared TemplateArgument
- if (Iter.isEnd() && ArgExpr->isValueDependent())
+ // from the desugared TemplateArgument, otherwise expression needs to
+ // be evaluatable.
+ if (Iter.isEnd() && ArgExpr->isValueDependent()) {
switch (Iter.getDesugar().getKind()) {
case TemplateArgument::Integral:
- return Iter.getDesugar().getAsIntegral();
+ Int = Iter.getDesugar().getAsIntegral();
+ return true;
case TemplateArgument::Expression:
ArgExpr = Iter.getDesugar().getAsExpr();
- return ArgExpr->EvaluateKnownConstInt(Context);
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
- return ArgExpr->EvaluateKnownConstInt(Context);
+ } else if (ArgExpr->isEvaluatable(Context)) {
+ Int = ArgExpr->EvaluateKnownConstInt(Context);
+ return true;
+ }
+
+ return false;
}
/// GetValueDecl - Retrieves the template Decl argument, including
@@ -1119,16 +1220,40 @@ class TemplateDiff {
ArgExpr = Iter.getDesugar().getAsExpr();
return cast<DeclRefExpr>(ArgExpr)->getDecl();
default:
- assert(0 && "Unexpected template argument kind");
+ llvm_unreachable("Unexpected template argument kind");
}
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr);
if (!DRE) {
- DRE = cast<DeclRefExpr>(cast<UnaryOperator>(ArgExpr)->getSubExpr());
+ UnaryOperator *UO = dyn_cast<UnaryOperator>(ArgExpr->IgnoreParens());
+ if (!UO)
+ return nullptr;
+ DRE = cast<DeclRefExpr>(UO->getSubExpr());
}
return DRE->getDecl();
}
+ /// CheckForNullPtr - returns true if the expression can be evaluated as
+ /// a null pointer
+ bool CheckForNullPtr(Expr *E) {
+ assert(E && "Expected expression");
+
+ E = E->IgnoreParenCasts();
+ if (E->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull))
+ return true;
+
+ DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
+ if (!DRE)
+ return false;
+
+ VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+ if (!VD || !VD->hasInit())
+ return false;
+
+ return VD->getInit()->IgnoreParenCasts()->isNullPointerConstant(
+ Context, Expr::NPC_ValueDependentIsNull);
+ }
+
/// GetTemplateDecl - Retrieves the template template arguments, including
/// default arguments.
TemplateDecl *GetTemplateDecl(const TSTiterator &Iter,
@@ -1136,7 +1261,7 @@ class TemplateDiff {
bool isVariadic = DefaultTTPD->isParameterPack();
TemplateArgument TA = DefaultTTPD->getDefaultArgument().getArgument();
- TemplateDecl *DefaultTD = 0;
+ TemplateDecl *DefaultTD = nullptr;
if (TA.getKind() != TemplateArgument::Null)
DefaultTD = TA.getAsTemplate().getAsTemplateDecl();
@@ -1145,7 +1270,7 @@ class TemplateDiff {
if (!isVariadic)
return DefaultTD;
- return 0;
+ return nullptr;
}
/// IsSameConvertedInt - Returns true if both integers are equal when
@@ -1166,11 +1291,8 @@ class TemplateDiff {
if (!FromExpr || !ToExpr)
return false;
- FromExpr = FromExpr->IgnoreParens();
- ToExpr = ToExpr->IgnoreParens();
-
- DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr),
- *ToDRE = dyn_cast<DeclRefExpr>(ToExpr);
+ DeclRefExpr *FromDRE = dyn_cast<DeclRefExpr>(FromExpr->IgnoreParens()),
+ *ToDRE = dyn_cast<DeclRefExpr>(ToExpr->IgnoreParens());
if (FromDRE || ToDRE) {
if (!FromDRE || !ToDRE)
@@ -1180,8 +1302,12 @@ class TemplateDiff {
Expr::EvalResult FromResult, ToResult;
if (!FromExpr->EvaluateAsRValue(FromResult, Context) ||
- !ToExpr->EvaluateAsRValue(ToResult, Context))
- return false;
+ !ToExpr->EvaluateAsRValue(ToResult, Context)) {
+ llvm::FoldingSetNodeID FromID, ToID;
+ FromExpr->Profile(FromID, Context, true);
+ ToExpr->Profile(ToID, Context, true);
+ return FromID == ToID;
+ }
APValue &FromVal = FromResult.Val;
APValue &ToVal = ToResult.Val;
@@ -1235,8 +1361,8 @@ class TemplateDiff {
case DiffTree::Expression: {
Expr *FromExpr, *ToExpr;
Tree.GetNode(FromExpr, ToExpr);
- PrintExpr(FromExpr, ToExpr, Tree.FromDefault(), Tree.ToDefault(),
- Tree.NodeIsSame());
+ PrintExpr(FromExpr, ToExpr, Tree.FromNullPtr(), Tree.ToNullPtr(),
+ Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::TemplateTemplate: {
@@ -1262,7 +1388,8 @@ class TemplateDiff {
bool FromAddressOf, ToAddressOf;
Tree.GetNode(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf);
PrintValueDecl(FromValueDecl, ToValueDecl, FromAddressOf, ToAddressOf,
- Tree.FromDefault(), Tree.ToDefault(), Tree.NodeIsSame());
+ Tree.FromNullPtr(), Tree.ToNullPtr(), Tree.FromDefault(),
+ Tree.ToDefault(), Tree.NodeIsSame());
return;
}
case DiffTree::Template: {
@@ -1341,7 +1468,7 @@ class TemplateDiff {
"Only one template argument may be missing.");
if (Same) {
- OS << FromType.getAsString();
+ OS << FromType.getAsString(Policy);
return;
}
@@ -1349,22 +1476,22 @@ class TemplateDiff {
FromType.getLocalUnqualifiedType() ==
ToType.getLocalUnqualifiedType()) {
Qualifiers FromQual = FromType.getLocalQualifiers(),
- ToQual = ToType.getLocalQualifiers(),
- CommonQual;
+ ToQual = ToType.getLocalQualifiers();
PrintQualifiers(FromQual, ToQual);
FromType.getLocalUnqualifiedType().print(OS, Policy);
return;
}
std::string FromTypeStr = FromType.isNull() ? "(no argument)"
- : FromType.getAsString();
+ : FromType.getAsString(Policy);
std::string ToTypeStr = ToType.isNull() ? "(no argument)"
- : ToType.getAsString();
+ : ToType.getAsString(Policy);
// Switch to canonical typename if it is better.
// TODO: merge this with other aka printing above.
if (FromTypeStr == ToTypeStr) {
- std::string FromCanTypeStr = FromType.getCanonicalType().getAsString();
- std::string ToCanTypeStr = ToType.getCanonicalType().getAsString();
+ std::string FromCanTypeStr =
+ FromType.getCanonicalType().getAsString(Policy);
+ std::string ToCanTypeStr = ToType.getCanonicalType().getAsString(Policy);
if (FromCanTypeStr != ToCanTypeStr) {
FromTypeStr = FromCanTypeStr;
ToTypeStr = ToCanTypeStr;
@@ -1388,36 +1515,41 @@ class TemplateDiff {
/// PrintExpr - Prints out the expr template arguments, highlighting argument
/// differences.
- void PrintExpr(const Expr *FromExpr, const Expr *ToExpr,
- bool FromDefault, bool ToDefault, bool Same) {
+ void PrintExpr(const Expr *FromExpr, const Expr *ToExpr, bool FromNullPtr,
+ bool ToNullPtr, bool FromDefault, bool ToDefault, bool Same) {
assert((FromExpr || ToExpr) &&
"Only one template argument may be missing.");
if (Same) {
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- PrintExpr(FromExpr);
+ PrintExpr(FromExpr, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- PrintExpr(ToExpr);
+ PrintExpr(ToExpr, ToNullPtr);
Unbold();
OS << ']';
}
}
/// PrintExpr - Actual formatting and printing of expressions.
- void PrintExpr(const Expr *E) {
- if (!E)
- OS << "(no argument)";
- else
- E->printPretty(OS, 0, Policy); return;
+ void PrintExpr(const Expr *E, bool NullPtr = false) {
+ if (E) {
+ E->printPretty(OS, nullptr, Policy);
+ return;
+ }
+ if (NullPtr) {
+ OS << "nullptr";
+ return;
+ }
+ OS << "(no argument)";
}
/// PrintTemplateTemplate - Handles printing of template template arguments,
@@ -1487,6 +1619,8 @@ class TemplateDiff {
Bold();
}
OS << Val.toString(10);
+ } else if (E) {
+ PrintExpr(E);
} else {
OS << "(no argument)";
}
@@ -1507,35 +1641,46 @@ class TemplateDiff {
return true;
}
+ void PrintValueDecl(ValueDecl *VD, bool AddressOf, bool NullPtr) {
+ if (VD) {
+ if (AddressOf)
+ OS << "&";
+ OS << VD->getName();
+ return;
+ }
+
+ if (NullPtr) {
+ OS << "nullptr";
+ return;
+ }
+
+ OS << "(no argument)";
+ }
+
/// PrintDecl - Handles printing of Decl arguments, highlighting
/// argument differences.
void PrintValueDecl(ValueDecl *FromValueDecl, ValueDecl *ToValueDecl,
- bool FromAddressOf, bool ToAddressOf, bool FromDefault,
- bool ToDefault, bool Same) {
- assert((FromValueDecl || ToValueDecl) &&
+ bool FromAddressOf, bool ToAddressOf, bool FromNullPtr,
+ bool ToNullPtr, bool FromDefault, bool ToDefault,
+ bool Same) {
+ assert((FromValueDecl || FromNullPtr || ToValueDecl || ToNullPtr) &&
"Only one Decl argument may be NULL");
if (Same) {
- OS << FromValueDecl->getName();
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
} else if (!PrintTree) {
OS << (FromDefault ? "(default) " : "");
Bold();
- if (FromAddressOf)
- OS << "&";
- OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
Unbold();
} else {
OS << (FromDefault ? "[(default) " : "[");
Bold();
- if (FromAddressOf)
- OS << "&";
- OS << (FromValueDecl ? FromValueDecl->getName() : "(no argument)");
+ PrintValueDecl(FromValueDecl, FromAddressOf, FromNullPtr);
Unbold();
OS << " != " << (ToDefault ? "(default) " : "");
Bold();
- if (ToAddressOf)
- OS << "&";
- OS << (ToValueDecl ? ToValueDecl->getName() : "(no argument)");
+ PrintValueDecl(ToValueDecl, ToAddressOf, ToNullPtr);
Unbold();
OS << ']';
}
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 670fd0ed3a93..df7a2cb4712b 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -149,11 +149,43 @@ namespace {
}
};
+ class ChildDumper {
+ ASTDumper &Dumper;
+
+ const Decl *Prev;
+ bool PrevRef;
+ public:
+ ChildDumper(ASTDumper &Dumper) : Dumper(Dumper), Prev(nullptr) {}
+ ~ChildDumper() {
+ if (Prev) {
+ Dumper.lastChild();
+ dump(nullptr);
+ }
+ }
+
+ // FIXME: This should take an arbitrary callable as the dumping action.
+ void dump(const Decl *D, bool Ref = false) {
+ if (Prev) {
+ if (PrevRef)
+ Dumper.dumpDeclRef(Prev);
+ else
+ Dumper.dumpDecl(Prev);
+ }
+ Prev = D;
+ PrevRef = Ref;
+ }
+ void dumpRef(const Decl *D) { dump(D, true); }
+
+ // Give up ownership of the children of the node. By calling this,
+ // the caller takes back responsibility for calling lastChild().
+ void release() { dump(nullptr); }
+ };
+
public:
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM)
: OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
- LastLocFilename(""), LastLocLine(~0U), FC(0),
+ LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
@@ -184,7 +216,7 @@ namespace {
void dumpBareType(QualType T);
void dumpType(QualType T);
void dumpBareDeclRef(const Decl *Node);
- void dumpDeclRef(const Decl *Node, const char *Label = 0);
+ void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
void dumpName(const NamedDecl *D);
bool hasNodes(const DeclContext *DC);
void dumpDeclContext(const DeclContext *DC);
@@ -222,6 +254,13 @@ namespace {
void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
void VisitCXXRecordDecl(const CXXRecordDecl *D);
void VisitStaticAssertDecl(const StaticAssertDecl *D);
+ template<typename SpecializationDecl>
+ void VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly);
+ template<typename TemplateDecl>
+ void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
void VisitClassTemplateDecl(const ClassTemplateDecl *D);
void VisitClassTemplateSpecializationDecl(
@@ -276,6 +315,7 @@ namespace {
void VisitIntegerLiteral(const IntegerLiteral *Node);
void VisitFloatingLiteral(const FloatingLiteral *Node);
void VisitStringLiteral(const StringLiteral *Str);
+ void VisitInitListExpr(const InitListExpr *ILE);
void VisitUnaryOperator(const UnaryOperator *Node);
void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
void VisitMemberExpr(const MemberExpr *Node);
@@ -405,6 +445,9 @@ void ASTDumper::dumpPointer(const void *Ptr) {
}
void ASTDumper::dumpLocation(SourceLocation Loc) {
+ if (!SM)
+ return;
+
ColorScope Color(*this, LocationColor);
SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
@@ -511,17 +554,14 @@ bool ASTDumper::hasNodes(const DeclContext *DC) {
void ASTDumper::dumpDeclContext(const DeclContext *DC) {
if (!DC)
return;
- bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
- for (DeclContext::decl_iterator I = DC->noload_decls_begin(),
- E = DC->noload_decls_end();
- I != E; ++I) {
- DeclContext::decl_iterator Next = I;
- ++Next;
- if (Next == E && !HasUndeserializedDecls)
- lastChild();
- dumpDecl(*I);
- }
- if (HasUndeserializedDecls) {
+
+ ChildDumper Children(*this);
+ for (auto *D : DC->noload_decls())
+ Children.dump(D);
+
+ if (DC->hasExternalLexicalStorage()) {
+ Children.release();
+
lastChild();
IndentScope Indent(*this);
ColorScope Color(*this, UndeserializedColor);
@@ -580,6 +620,7 @@ void ASTDumper::dumpAttr(const Attr *A) {
IndentScope Indent(*this);
{
ColorScope Color(*this, AttrColor);
+
switch (A->getKind()) {
#define ATTR(X) case attr::X: OS << #X; break;
#include "clang/Basic/AttrList.inc"
@@ -589,6 +630,10 @@ void ASTDumper::dumpAttr(const Attr *A) {
}
dumpPointer(A);
dumpSourceRange(A->getRange());
+ if (A->isInherited())
+ OS << " Inherited";
+ if (A->isImplicit())
+ OS << " Implicit";
#include "clang/AST/AttrDump.inc"
}
@@ -753,13 +798,23 @@ void ASTDumper::dumpDecl(const Decl *D) {
OS << " parent " << cast<Decl>(D->getDeclContext());
dumpPreviousDecl(OS, D);
dumpSourceRange(D->getSourceRange());
+ OS << ' ';
+ dumpLocation(D->getLocation());
if (Module *M = D->getOwningModule())
OS << " in " << M->getFullModuleName();
if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
if (ND->isHidden())
OS << " hidden";
+ if (D->isImplicit())
+ OS << " implicit";
+ if (D->isUsed())
+ OS << " used";
+ else if (D->isReferenced())
+ OS << " referenced";
+ if (D->isInvalidDecl())
+ OS << " invalid";
- bool HasAttrs = D->attr_begin() != D->attr_end();
+ bool HasAttrs = D->hasAttrs();
const FullComment *Comment =
D->getASTContext().getLocalCommentForDeclUncached(D);
// Decls within functions are visited by the body
@@ -781,9 +836,6 @@ void ASTDumper::dumpDecl(const Decl *D) {
lastChild();
dumpFullComment(Comment);
- if (D->isInvalidDecl())
- OS << " invalid";
-
setMoreChildren(false);
if (HasDeclContext)
dumpDeclContext(cast<DeclContext>(D));
@@ -835,13 +887,10 @@ void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
dumpName(D);
dumpType(D->getType());
- for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
- E = D->chain_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ for (auto *Child : D->chain())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
@@ -975,6 +1024,11 @@ void ASTDumper::VisitVarDecl(const VarDecl *D) {
if (D->isNRVOVariable())
OS << " nrvo";
if (D->hasInit()) {
+ switch (D->getInitStyle()) {
+ case VarDecl::CInit: OS << " cinit"; break;
+ case VarDecl::CallInit: OS << " callinit"; break;
+ case VarDecl::ListInit: OS << " listinit"; break;
+ }
lastChild();
dumpStmt(D->getInit());
}
@@ -1027,15 +1081,13 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
if (!D->isCompleteDefinition())
return;
- for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
- E = D->bases_end();
- I != E; ++I) {
+ for (const auto &I : D->bases()) {
IndentScope Indent(*this);
- if (I->isVirtual())
+ if (I.isVirtual())
OS << "virtual ";
- dumpAccessSpecifier(I->getAccessSpecifier());
- dumpType(I->getType());
- if (I->isPackExpansion())
+ dumpAccessSpecifier(I.getAccessSpecifier());
+ dumpType(I.getType());
+ if (I.isPackExpansion())
OS << "...";
}
}
@@ -1046,63 +1098,69 @@ void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
dumpStmt(D->getMessage());
}
-void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
- dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
- dumpDecl(D->getTemplatedDecl());
- for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
- E = D->spec_end();
- I != E; ++I) {
- FunctionTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
+template<typename SpecializationDecl>
+void ASTDumper::VisitTemplateDeclSpecialization(ChildDumper &Children,
+ const SpecializationDecl *D,
+ bool DumpExplicitInst,
+ bool DumpRefOnly) {
+ bool DumpedAny = false;
+ for (auto *RedeclWithBadType : D->redecls()) {
+ // FIXME: The redecls() range sometimes has elements of a less-specific
+ // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
+ // us TagDecls, and should give CXXRecordDecls).
+ auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+ if (!Redecl) {
+ // Found the injected-class-name for a class template. This will be dumped
+ // as part of its surrounding class so we don't need to dump it here.
+ assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
+ "expected an injected-class-name");
+ continue;
+ }
+
+ switch (Redecl->getTemplateSpecializationKind()) {
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
+ if (!DumpExplicitInst)
+ break;
+ // Fall through.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ Children.dump(Redecl, DumpRefOnly);
+ DumpedAny = true;
break;
case TSK_ExplicitSpecialization:
- dumpDeclRef(*I);
break;
}
}
+
+ // Ensure we dump at least one decl for each specialization.
+ if (!DumpedAny)
+ Children.dumpRef(D);
}
-void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+template<typename TemplateDecl>
+void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
+ bool DumpExplicitInst) {
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- ClassTemplateDecl::spec_iterator I = D->spec_begin();
- ClassTemplateDecl::spec_iterator E = D->spec_end();
- if (I == E)
- lastChild();
- dumpDecl(D->getTemplatedDecl());
- for (; I != E; ++I) {
- ClassTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
- break;
- case TSK_ExplicitSpecialization:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- dumpDeclRef(*I);
- break;
- }
- }
+ ChildDumper Children(*this);
+ Children.dump(D->getTemplatedDecl());
+
+ for (auto *Child : D->specializations())
+ VisitTemplateDeclSpecialization(Children, Child, DumpExplicitInst,
+ !D->isCanonicalDecl());
+}
+
+void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
+ // FIXME: We don't add a declaration of a function template specialization
+ // to its context when it's explicitly instantiated, so dump explicit
+ // instantiations when we dump the template itself.
+ VisitTemplateDecl(D, true);
+}
+
+void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
+ VisitTemplateDecl(D, false);
}
void ASTDumper::VisitClassTemplateSpecializationDecl(
@@ -1125,34 +1183,7 @@ void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
}
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
- dumpName(D);
- dumpTemplateParameters(D->getTemplateParameters());
-
- VarTemplateDecl::spec_iterator I = D->spec_begin();
- VarTemplateDecl::spec_iterator E = D->spec_end();
- if (I == E)
- lastChild();
- dumpDecl(D->getTemplatedDecl());
- for (; I != E; ++I) {
- VarTemplateDecl::spec_iterator Next = I;
- ++Next;
- if (Next == E)
- lastChild();
- switch (I->getTemplateSpecializationKind()) {
- case TSK_Undeclared:
- case TSK_ImplicitInstantiation:
- if (D == D->getCanonicalDecl())
- dumpDecl(*I);
- else
- dumpDeclRef(*I);
- break;
- case TSK_ExplicitSpecialization:
- case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
- dumpDeclRef(*I);
- break;
- }
- }
+ VisitTemplateDecl(D, false);
}
void ASTDumper::VisitVarTemplateSpecializationDecl(
@@ -1175,8 +1206,10 @@ void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
if (D->isParameterPack())
OS << " ...";
dumpName(D);
- if (D->hasDefaultArgument())
- dumpType(D->getDefaultArgument());
+ if (D->hasDefaultArgument()) {
+ lastChild();
+ dumpTemplateArgument(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
@@ -1184,8 +1217,10 @@ void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
if (D->isParameterPack())
OS << " ...";
dumpName(D);
- if (D->hasDefaultArgument())
- dumpStmt(D->getDefaultArgument());
+ if (D->hasDefaultArgument()) {
+ lastChild();
+ dumpTemplateArgument(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitTemplateTemplateParmDecl(
@@ -1194,8 +1229,10 @@ void ASTDumper::VisitTemplateTemplateParmDecl(
OS << " ...";
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
- if (D->hasDefaultArgument())
+ if (D->hasDefaultArgument()) {
+ lastChild();
dumpTemplateArgumentLoc(D->getDefaultArgument());
+ }
}
void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
@@ -1252,8 +1289,6 @@ void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
dumpType(D->getType());
if (D->getSynthesize())
OS << " synthesize";
- if (D->getBackingIvarReferencedInAccessor())
- OS << " BackingIvarReferencedInAccessor";
switch (D->getAccessControl()) {
case ObjCIvarDecl::None:
@@ -1280,7 +1315,7 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
else
OS << " +";
dumpName(D);
- dumpType(D->getResultType());
+ dumpType(D->getReturnType());
bool OldMoreChildren = hasMoreChildren();
bool IsVariadic = D->isVariadic();
@@ -1338,28 +1373,20 @@ void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
dumpName(D);
- for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ for (auto *Child : D->protocols())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
dumpName(D);
dumpDeclRef(D->getSuperClass(), "super");
- if (D->protocol_begin() == D->protocol_end())
- lastChild();
- dumpDeclRef(D->getImplementation());
- for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
- E = D->protocol_end();
- I != E; ++I) {
- if (I + 1 == E)
- lastChild();
- dumpDeclRef(*I);
- }
+
+ ChildDumper Children(*this);
+ Children.dumpRef(D->getImplementation());
+ for (auto *Child : D->protocols())
+ Children.dumpRef(Child);
}
void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
@@ -1438,9 +1465,8 @@ void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
}
void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
- for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
- I != E; ++I)
- dumpDecl(*I);
+ for (auto I : D->params())
+ dumpDecl(I);
if (D->isVariadic()) {
IndentScope Indent(*this);
@@ -1451,20 +1477,19 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
IndentScope Indent(*this);
OS << "capture this";
}
- for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
- I != E; ++I) {
+ for (const auto &I : D->captures()) {
IndentScope Indent(*this);
OS << "capture";
- if (I->isByRef())
+ if (I.isByRef())
OS << " byref";
- if (I->isNested())
+ if (I.isNested())
OS << " nested";
- if (I->getVariable()) {
+ if (I.getVariable()) {
OS << ' ';
- dumpBareDeclRef(I->getVariable());
+ dumpBareDeclRef(I.getVariable());
}
- if (I->hasCopyExpr())
- dumpStmt(I->getCopyExpr());
+ if (I.hasCopyExpr())
+ dumpStmt(I.getCopyExpr());
}
lastChild();
dumpStmt(D->getBody());
@@ -1675,6 +1700,7 @@ void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
case PredefinedExpr::FuncDName: OS << " __FUNCDNAME__"; break;
case PredefinedExpr::LFunction: OS << " L__FUNCTION__"; break;
case PredefinedExpr::PrettyFunction: OS << " __PRETTY_FUNCTION__";break;
+ case PredefinedExpr::FuncSig: OS << " __FUNCSIG__"; break;
}
}
@@ -1705,6 +1731,22 @@ void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
Str->outputString(OS);
}
+void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
+ VisitExpr(ILE);
+ if (auto *Filler = ILE->getArrayFiller()) {
+ if (!ILE->getNumInits())
+ lastChild();
+ IndentScope Indent(*this);
+ OS << "array filler";
+ lastChild();
+ dumpStmt(Filler);
+ }
+ if (auto *Field = ILE->getInitializedFieldInUnion()) {
+ OS << " field ";
+ dumpBareDeclRef(Field);
+ }
+}
+
void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
VisitExpr(Node);
OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
@@ -1849,7 +1891,8 @@ void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
VisitExpr(Node);
- OS << " selector=" << Node->getSelector().getAsString();
+ OS << " selector=";
+ Node->getSelector().print(OS);
switch (Node->getReceiverKind()) {
case ObjCMessageExpr::Instance:
break;
@@ -1871,7 +1914,8 @@ void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
VisitExpr(Node);
- OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
+ OS << " selector=";
+ Node->getBoxingMethod()->getSelector().print(OS);
}
void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
@@ -1890,7 +1934,8 @@ void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
VisitExpr(Node);
- OS << " " << Node->getSelector().getAsString();
+ OS << " ";
+ Node->getSelector().print(OS);
}
void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
@@ -1904,13 +1949,13 @@ void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
if (Node->isImplicitProperty()) {
OS << " Kind=MethodRef Getter=\"";
if (Node->getImplicitPropertyGetter())
- OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
+ Node->getImplicitPropertyGetter()->getSelector().print(OS);
else
OS << "(null)";
OS << "\" Setter=\"";
if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
- OS << Setter->getSelector().getAsString();
+ Setter->getSelector().print(OS);
else
OS << "(null)";
OS << "\"";
@@ -1937,7 +1982,7 @@ void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
else
OS << " Kind=DictionarySubscript GetterForDictionary=\"";
if (Node->getAtIndexMethodDecl())
- OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
+ Node->getAtIndexMethodDecl()->getSelector().print(OS);
else
OS << "(null)";
@@ -1946,7 +1991,7 @@ void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
else
OS << "\" SetterForDictionary=\"";
if (Node->setAtIndexMethodDecl())
- OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
+ Node->setAtIndexMethodDecl()->getSelector().print(OS);
else
OS << "(null)";
}
@@ -1975,7 +2020,7 @@ void ASTDumper::dumpFullComment(const FullComment *C) {
FC = C;
dumpComment(C);
- FC = 0;
+ FC = nullptr;
}
void ASTDumper::dumpComment(const Comment *C) {
@@ -2065,7 +2110,7 @@ void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
}
- if (C->isParamIndexValid())
+ if (C->isParamIndexValid() && !C->isVarArgParam())
OS << " ParamIndex=" << C->getParamIndex();
}
@@ -2106,27 +2151,25 @@ void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
// Decl method implementations
//===----------------------------------------------------------------------===//
-void Decl::dump() const {
- dump(llvm::errs());
-}
+LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
-void Decl::dump(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
&getASTContext().getSourceManager());
P.dumpDecl(this);
}
-void Decl::dumpColor() const {
+LLVM_DUMP_METHOD void Decl::dumpColor() const {
ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
&getASTContext().getSourceManager(), /*ShowColors*/true);
P.dumpDecl(this);
}
-void DeclContext::dumpLookups() const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
dumpLookups(llvm::errs());
}
-void DeclContext::dumpLookups(raw_ostream &OS) const {
+LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS) const {
const DeclContext *DC = this;
while (!DC->isTranslationUnit())
DC = DC->getParent();
@@ -2139,22 +2182,22 @@ void DeclContext::dumpLookups(raw_ostream &OS) const {
// Stmt method implementations
//===----------------------------------------------------------------------===//
-void Stmt::dump(SourceManager &SM) const {
+LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
dump(llvm::errs(), SM);
}
-void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
- ASTDumper P(OS, 0, &SM);
+LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
+ ASTDumper P(OS, nullptr, &SM);
P.dumpStmt(this);
}
-void Stmt::dump() const {
- ASTDumper P(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Stmt::dump() const {
+ ASTDumper P(llvm::errs(), nullptr, nullptr);
P.dumpStmt(this);
}
-void Stmt::dumpColor() const {
- ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
+LLVM_DUMP_METHOD void Stmt::dumpColor() const {
+ ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
P.dumpStmt(this);
}
@@ -2162,11 +2205,11 @@ void Stmt::dumpColor() const {
// Comment method implementations
//===----------------------------------------------------------------------===//
-void Comment::dump() const {
- dump(llvm::errs(), 0, 0);
+LLVM_DUMP_METHOD void Comment::dump() const {
+ dump(llvm::errs(), nullptr, nullptr);
}
-void Comment::dump(const ASTContext &Context) const {
+LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
dump(llvm::errs(), &Context.getCommentCommandTraits(),
&Context.getSourceManager());
}
@@ -2178,8 +2221,8 @@ void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
D.dumpFullComment(FC);
}
-void Comment::dumpColor() const {
+LLVM_DUMP_METHOD void Comment::dumpColor() const {
const FullComment *FC = dyn_cast<FullComment>(this);
- ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
+ ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
D.dumpFullComment(FC);
}
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index e16015b7c4ed..b0e0b1dc9e00 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -81,7 +81,7 @@ namespace clang {
bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
DeclContext *&LexicalDC, DeclarationName &Name,
SourceLocation &Loc);
- void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
+ void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = nullptr);
void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
DeclarationNameInfo& To);
void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
@@ -407,10 +407,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
+ case Type::Adjusted:
case Type::Decayed:
if (!IsStructurallyEquivalent(Context,
- cast<DecayedType>(T1)->getPointeeType(),
- cast<DecayedType>(T2)->getPointeeType()))
+ cast<AdjustedType>(T1)->getOriginalType(),
+ cast<AdjustedType>(T2)->getOriginalType()))
return false;
break;
@@ -534,12 +535,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::FunctionProto: {
const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
- if (Proto1->getNumArgs() != Proto2->getNumArgs())
+ if (Proto1->getNumParams() != Proto2->getNumParams())
return false;
- for (unsigned I = 0, N = Proto1->getNumArgs(); I != N; ++I) {
- if (!IsStructurallyEquivalent(Context,
- Proto1->getArgType(I),
- Proto2->getArgType(I)))
+ for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
+ Proto2->getParamType(I)))
return false;
}
if (Proto1->isVariadic() != Proto2->isVariadic())
@@ -570,9 +570,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::FunctionNoProto: {
const FunctionType *Function1 = cast<FunctionType>(T1);
const FunctionType *Function2 = cast<FunctionType>(T2);
- if (!IsStructurallyEquivalent(Context,
- Function1->getResultType(),
- Function2->getResultType()))
+ if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
+ Function2->getReturnType()))
return false;
if (Function1->getExtInfo() != Function2->getExtInfo())
return false;
@@ -931,10 +930,8 @@ static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) {
return None;
unsigned Index = 0;
- for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
- DEnd = Owner->noload_decls_end();
- D != DEnd; ++D) {
- FieldDecl *F = dyn_cast<FieldDecl>(*D);
+ for (const auto *D : Owner->noload_decls()) {
+ const auto *F = dyn_cast<FieldDecl>(D);
if (!F || !F->isAnonymousStructOrUnion())
continue;
@@ -1586,7 +1583,7 @@ QualType
ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
// FIXME: What happens if we're importing a function without a prototype
// into C++? Should we make it variadic?
- QualType ToResultType = Importer.Import(T->getResultType());
+ QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
return QualType();
@@ -1595,16 +1592,14 @@ ASTNodeImporter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) {
}
QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
- QualType ToResultType = Importer.Import(T->getResultType());
+ QualType ToResultType = Importer.Import(T->getReturnType());
if (ToResultType.isNull())
return QualType();
// Import argument types
SmallVector<QualType, 4> ArgTypes;
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- QualType ArgType = Importer.Import(*A);
+ for (const auto &A : T->param_types()) {
+ QualType ArgType = Importer.Import(A);
if (ArgType.isNull())
return QualType();
ArgTypes.push_back(ArgType);
@@ -1612,10 +1607,8 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
// Import exception types
SmallVector<QualType, 4> ExceptionTypes;
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- QualType ExceptionType = Importer.Import(*E);
+ for (const auto &E : T->exceptions()) {
+ QualType ExceptionType = Importer.Import(E);
if (ExceptionType.isNull())
return QualType();
ExceptionTypes.push_back(ExceptionType);
@@ -1631,7 +1624,7 @@ QualType ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
ToEPI.RefQualifier = FromEPI.RefQualifier;
ToEPI.NumExceptions = ExceptionTypes.size();
ToEPI.Exceptions = ExceptionTypes.data();
- ToEPI.ConsumedArguments = FromEPI.ConsumedArguments;
+ ToEPI.ConsumedParameters = FromEPI.ConsumedParameters;
ToEPI.ExceptionSpecType = FromEPI.ExceptionSpecType;
ToEPI.NoexceptExpr = Importer.Import(FromEPI.NoexceptExpr);
ToEPI.ExceptionSpecDecl = cast_or_null<FunctionDecl>(
@@ -1756,7 +1749,7 @@ QualType ASTNodeImporter::VisitTemplateSpecializationType(
}
QualType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
- NestedNameSpecifier *ToQualifier = 0;
+ NestedNameSpecifier *ToQualifier = nullptr;
// Note: the qualifier in an ElaboratedType is optional.
if (T->getQualifier()) {
ToQualifier = Importer.Import(T->getQualifier());
@@ -1787,11 +1780,9 @@ QualType ASTNodeImporter::VisitObjCObjectType(const ObjCObjectType *T) {
return QualType();
SmallVector<ObjCProtocolDecl *, 4> Protocols;
- for (ObjCObjectType::qual_iterator P = T->qual_begin(),
- PEnd = T->qual_end();
- P != PEnd; ++P) {
+ for (auto *P : T->quals()) {
ObjCProtocolDecl *Protocol
- = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(*P));
+ = dyn_cast_or_null<ObjCProtocolDecl>(Importer.Import(P));
if (!Protocol)
return QualType();
Protocols.push_back(Protocol);
@@ -1909,11 +1900,8 @@ void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
return;
}
- for (DeclContext::decl_iterator From = FromDC->decls_begin(),
- FromEnd = FromDC->decls_end();
- From != FromEnd;
- ++From)
- Importer.Import(*From);
+ for (auto *From : FromDC->decls())
+ Importer.Import(From);
}
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
@@ -1946,6 +1934,7 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.HasProtectedFields = FromData.HasProtectedFields;
ToData.HasPublicFields = FromData.HasPublicFields;
ToData.HasMutableFields = FromData.HasMutableFields;
+ ToData.HasVariantMembers = FromData.HasVariantMembers;
ToData.HasOnlyCMembers = FromData.HasOnlyCMembers;
ToData.HasInClassInitializer = FromData.HasInClassInitializer;
ToData.HasUninitializedReferenceMember
@@ -1986,29 +1975,25 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
ToData.IsLambda = FromData.IsLambda;
SmallVector<CXXBaseSpecifier *, 4> Bases;
- for (CXXRecordDecl::base_class_iterator
- Base1 = FromCXX->bases_begin(),
- FromBaseEnd = FromCXX->bases_end();
- Base1 != FromBaseEnd;
- ++Base1) {
- QualType T = Importer.Import(Base1->getType());
+ for (const auto &Base1 : FromCXX->bases()) {
+ QualType T = Importer.Import(Base1.getType());
if (T.isNull())
return true;
SourceLocation EllipsisLoc;
- if (Base1->isPackExpansion())
- EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
+ if (Base1.isPackExpansion())
+ EllipsisLoc = Importer.Import(Base1.getEllipsisLoc());
// Ensure that we have a definition for the base.
- ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
+ ImportDefinitionIfNeeded(Base1.getType()->getAsCXXRecordDecl());
Bases.push_back(
new (Importer.getToContext())
- CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
- Base1->isVirtual(),
- Base1->isBaseOfClass(),
- Base1->getAccessSpecifierAsWritten(),
- Importer.Import(Base1->getTypeSourceInfo()),
+ CXXBaseSpecifier(Importer.Import(Base1.getSourceRange()),
+ Base1.isVirtual(),
+ Base1.isBaseOfClass(),
+ Base1.getAccessSpecifierAsWritten(),
+ Importer.Import(Base1.getTypeSourceInfo()),
EllipsisLoc));
}
if (!Bases.empty())
@@ -2075,8 +2060,8 @@ TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
P != PEnd; ++P) {
Decl *To = Importer.Import(*P);
if (!To)
- return 0;
-
+ return nullptr;
+
ToParams.push_back(cast<NamedDecl>(To));
}
@@ -2236,7 +2221,7 @@ bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
Decl *ASTNodeImporter::VisitDecl(Decl *D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
- return 0;
+ return nullptr;
}
Decl *ASTNodeImporter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
@@ -2254,9 +2239,9 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
- NamespaceDecl *MergeWithNamespace = 0;
+ return nullptr;
+
+ NamespaceDecl *MergeWithNamespace = nullptr;
if (!Name) {
// This is an anonymous namespace. Adopt an existing anonymous
// namespace if we can.
@@ -2296,7 +2281,7 @@ Decl *ASTNodeImporter::VisitNamespaceDecl(NamespaceDecl *D) {
D->isInline(),
Importer.Import(D->getLocStart()),
Loc, Name.getAsIdentifierInfo(),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
ToNamespace->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToNamespace);
@@ -2322,8 +2307,8 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// If this typedef is not in block scope, determine whether we've
// seen a typedef with the same name (that we can merge with) or any
// other entity by that name (which name lookup could conflict with).
@@ -2350,15 +2335,15 @@ Decl *ASTNodeImporter::VisitTypedefNameDecl(TypedefNameDecl *D, bool IsAlias) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
// Import the underlying type of this typedef;
QualType T = Importer.Import(D->getUnderlyingType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the new typedef node.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
SourceLocation StartL = Importer.Import(D->getLocStart());
@@ -2396,8 +2381,8 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Figure out what enum name we're looking for.
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
@@ -2440,7 +2425,7 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// Create the enum declaration.
EnumDecl *D2 = EnumDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getLocStart()),
- Loc, Name.getAsIdentifierInfo(), 0,
+ Loc, Name.getAsIdentifierInfo(), nullptr,
D->isScoped(), D->isScopedUsingClassTag(),
D->isFixed());
// Import the qualifier, if any.
@@ -2453,12 +2438,12 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
// Import the integer type.
QualType ToIntegerType = Importer.Import(D->getIntegerType());
if (ToIntegerType.isNull())
- return 0;
+ return nullptr;
D2->setIntegerType(ToIntegerType);
// Import the definition
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return 0;
+ return nullptr;
return D2;
}
@@ -2471,8 +2456,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -2481,8 +2466,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Figure out what structure name we're looking for.
unsigned IDNS = Decl::IDNS_Tag;
DeclarationName SearchName = Name;
@@ -2493,7 +2478,7 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
IDNS |= Decl::IDNS_Ordinary;
// We may already have a record of the same name; try to find and match it.
- RecordDecl *AdoptDecl = 0;
+ RecordDecl *AdoptDecl = nullptr;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2538,6 +2523,21 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
} else if (!D->isCompleteDefinition()) {
// We have a forward declaration of this type, so adopt that forward
// declaration rather than building a new one.
+
+ // If one or both can be completed from external storage then try one
+ // last time to complete and compare them before doing this.
+
+ if (FoundRecord->hasExternalLexicalStorage() &&
+ !FoundRecord->isCompleteDefinition())
+ FoundRecord->getASTContext().getExternalSource()->CompleteType(FoundRecord);
+ if (D->hasExternalLexicalStorage())
+ D->getASTContext().getExternalSource()->CompleteType(D);
+
+ if (FoundRecord->isCompleteDefinition() &&
+ D->isCompleteDefinition() &&
+ !IsStructuralMatch(D, FoundRecord))
+ continue;
+
AdoptDecl = FoundRecord;
continue;
} else if (!SearchName) {
@@ -2581,8 +2581,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2, IDK_Default))
- return 0;
-
+ return nullptr;
+
return D2;
}
@@ -2592,11 +2592,11 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
// Determine whether there are any other declarations with the same name and
// in the same context.
@@ -2623,14 +2623,14 @@ Decl *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
Expr *Init = Importer.Import(D->getInitExpr());
if (D->getInitExpr() && !Init)
- return 0;
-
+ return nullptr;
+
EnumConstantDecl *ToEnumerator
= EnumConstantDecl::Create(Importer.getToContext(), cast<EnumDecl>(DC), Loc,
Name.getAsIdentifierInfo(), T,
@@ -2648,7 +2648,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return 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.
@@ -2694,7 +2694,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
@@ -2716,7 +2716,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
FromEPI.NoexceptExpr) {
FunctionProtoType::ExtProtoInfo DefaultEPI;
FromTy = Importer.getFromContext().getFunctionType(
- FromFPT->getResultType(), FromFPT->getArgTypes(), DefaultEPI);
+ FromFPT->getReturnType(), FromFPT->getParamTypes(), DefaultEPI);
usedDifferentExceptionSpec = true;
}
}
@@ -2724,22 +2724,21 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Import the type.
QualType T = Importer.Import(FromTy);
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Import the function parameters.
SmallVector<ParmVarDecl *, 8> Parameters;
- for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end();
- P != PEnd; ++P) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*P));
+ for (auto P : D->params()) {
+ ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(P));
if (!ToP)
- return 0;
-
+ return nullptr;
+
Parameters.push_back(ToP);
}
// Create the imported function.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
- FunctionDecl *ToFunction = 0;
+ FunctionDecl *ToFunction = nullptr;
if (CXXConstructorDecl *FromConstructor = dyn_cast<CXXConstructorDecl>(D)) {
ToFunction = CXXConstructorDecl::Create(Importer.getToContext(),
cast<CXXRecordDecl>(DC),
@@ -2804,7 +2803,7 @@ Decl *ASTNodeImporter::VisitFunctionDecl(FunctionDecl *D) {
// Update FunctionProtoType::ExtProtoInfo.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
ToFunction->setType(T);
}
@@ -2838,10 +2837,8 @@ static unsigned getFieldIndex(Decl *F) {
return 0;
unsigned Index = 1;
- for (DeclContext::decl_iterator D = Owner->noload_decls_begin(),
- DEnd = Owner->noload_decls_end();
- D != DEnd; ++D) {
- if (*D == F)
+ for (const auto *D : Owner->noload_decls()) {
+ if (D == F)
return Index;
if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
@@ -2857,8 +2854,8 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Determine whether we've already imported this field.
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
@@ -2878,20 +2875,20 @@ Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Expr *BitWidth = Importer.Import(D->getBitWidth());
if (!BitWidth && D->getBitWidth())
- return 0;
-
+ return nullptr;
+
FieldDecl *ToField = FieldDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
@@ -2913,7 +2910,7 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Determine whether we've already imported this field.
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -2940,24 +2937,23 @@ Decl *ASTNodeImporter::VisitIndirectFieldDecl(IndirectFieldDecl *D) {
<< Name << D->getType() << FoundField->getType();
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
<< FoundField->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
NamedDecl **NamedChain =
new (Importer.getToContext())NamedDecl*[D->getChainingSize()];
unsigned i = 0;
- for (IndirectFieldDecl::chain_iterator PI = D->chain_begin(),
- PE = D->chain_end(); PI != PE; ++PI) {
- Decl* D = Importer.Import(*PI);
+ for (auto *PI : D->chain()) {
+ Decl *D = Importer.Import(PI);
if (!D)
- return 0;
+ return nullptr;
NamedChain[i++] = cast<NamedDecl>(D);
}
@@ -2978,8 +2974,8 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Determine whether we've already imported this ivar
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
@@ -2995,27 +2991,26 @@ Decl *ASTNodeImporter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
<< Name << D->getType() << FoundIvar->getType();
Importer.ToDiag(FoundIvar->getLocation(), diag::note_odr_value_here)
<< FoundIvar->getType();
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
Expr *BitWidth = Importer.Import(D->getBitWidth());
if (!BitWidth && D->getBitWidth())
- return 0;
-
+ return nullptr;
+
ObjCIvarDecl *ToIvar = ObjCIvarDecl::Create(Importer.getToContext(),
cast<ObjCContainerDecl>(DC),
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getAccessControl(),
- BitWidth, D->getSynthesize(),
- D->getBackingIvarReferencedInAccessor());
+ BitWidth, D->getSynthesize());
ToIvar->setLexicalDeclContext(LexicalDC);
Importer.Imported(D, ToIvar);
LexicalDC->addDeclInternal(ToIvar);
@@ -3029,12 +3024,12 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// Try to find a variable in our own ("to") context with the same name and
// in the same context as the variable we're importing.
if (D->isFileVarDecl()) {
- VarDecl *MergeWithVar = 0;
+ VarDecl *MergeWithVar = nullptr;
SmallVector<NamedDecl *, 4> ConflictingDecls;
unsigned IDNS = Decl::IDNS_Ordinary;
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3063,8 +3058,8 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
FoundVar->setType(T);
MergeWithVar = FoundVar;
break;
@@ -3115,15 +3110,15 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
ConflictingDecls.data(),
ConflictingDecls.size());
if (!Name)
- return 0;
+ return nullptr;
}
}
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported variable.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
VarDecl *ToVar = VarDecl::Create(Importer.getToContext(), DC,
@@ -3139,7 +3134,7 @@ Decl *ASTNodeImporter::VisitVarDecl(VarDecl *D) {
// Merge the initializer.
if (ImportDefinition(D, ToVar))
- return 0;
+ return nullptr;
return ToVar;
}
@@ -3152,16 +3147,16 @@ Decl *ASTNodeImporter::VisitImplicitParamDecl(ImplicitParamDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the parameter's type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported parameter.
ImplicitParamDecl *ToParm
= ImplicitParamDecl::Create(Importer.getToContext(), DC,
@@ -3178,23 +3173,23 @@ Decl *ASTNodeImporter::VisitParmVarDecl(ParmVarDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the parameter's type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Create the imported parameter.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
ParmVarDecl *ToParm = ParmVarDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getInnerLocStart()),
Loc, Name.getAsIdentifierInfo(),
T, TInfo, D->getStorageClass(),
- /*FIXME: Default argument*/ 0);
+ /*FIXME: Default argument*/nullptr);
ToParm->setHasInheritedDefaultArg(D->hasInheritedDefaultArg());
return Importer.Imported(D, ToParm);
}
@@ -3205,8 +3200,8 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3215,15 +3210,15 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
continue;
// Check return types.
- if (!Importer.IsStructurallyEquivalent(D->getResultType(),
- FoundMethod->getResultType())) {
+ if (!Importer.IsStructurallyEquivalent(D->getReturnType(),
+ FoundMethod->getReturnType())) {
Importer.ToDiag(Loc, diag::err_odr_objc_method_result_type_inconsistent)
- << D->isInstanceMethod() << Name
- << D->getResultType() << FoundMethod->getResultType();
+ << D->isInstanceMethod() << Name << D->getReturnType()
+ << FoundMethod->getReturnType();
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// Check the number of parameters.
@@ -3234,7 +3229,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// Check parameter types.
@@ -3249,7 +3244,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
<< (*P)->getType() << (*FoundP)->getType();
Importer.ToDiag((*FoundP)->getLocation(), diag::note_odr_value_here)
<< (*FoundP)->getType();
- return 0;
+ return nullptr;
}
}
@@ -3261,7 +3256,7 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
Importer.ToDiag(FoundMethod->getLocation(),
diag::note_odr_objc_method_here)
<< D->isInstanceMethod() << Name;
- return 0;
+ return nullptr;
}
// FIXME: Any other bits we need to merge?
@@ -3270,39 +3265,28 @@ Decl *ASTNodeImporter::VisitObjCMethodDecl(ObjCMethodDecl *D) {
}
// Import the result type.
- QualType ResultTy = Importer.Import(D->getResultType());
+ QualType ResultTy = Importer.Import(D->getReturnType());
if (ResultTy.isNull())
- return 0;
+ return nullptr;
+
+ TypeSourceInfo *ReturnTInfo = Importer.Import(D->getReturnTypeSourceInfo());
- TypeSourceInfo *ResultTInfo = Importer.Import(D->getResultTypeSourceInfo());
-
- ObjCMethodDecl *ToMethod
- = ObjCMethodDecl::Create(Importer.getToContext(),
- Loc,
- Importer.Import(D->getLocEnd()),
- Name.getObjCSelector(),
- ResultTy, ResultTInfo, DC,
- D->isInstanceMethod(),
- D->isVariadic(),
- D->isPropertyAccessor(),
- D->isImplicit(),
- D->isDefined(),
- D->getImplementationControl(),
- D->hasRelatedResultType());
+ ObjCMethodDecl *ToMethod = ObjCMethodDecl::Create(
+ Importer.getToContext(), Loc, Importer.Import(D->getLocEnd()),
+ Name.getObjCSelector(), ResultTy, ReturnTInfo, DC, D->isInstanceMethod(),
+ D->isVariadic(), D->isPropertyAccessor(), D->isImplicit(), D->isDefined(),
+ D->getImplementationControl(), D->hasRelatedResultType());
// FIXME: When we decide to merge method definitions, we'll need to
// deal with implicit parameters.
// Import the parameters
SmallVector<ParmVarDecl *, 5> ToParams;
- for (ObjCMethodDecl::param_iterator FromP = D->param_begin(),
- FromPEnd = D->param_end();
- FromP != FromPEnd;
- ++FromP) {
- ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(*FromP));
+ for (auto *FromP : D->params()) {
+ ParmVarDecl *ToP = cast_or_null<ParmVarDecl>(Importer.Import(FromP));
if (!ToP)
- return 0;
-
+ return nullptr;
+
ToParams.push_back(ToP);
}
@@ -3327,13 +3311,13 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
ObjCInterfaceDecl *ToInterface
= cast_or_null<ObjCInterfaceDecl>(Importer.Import(D->getClassInterface()));
if (!ToInterface)
- return 0;
-
+ return nullptr;
+
// Determine if we've already encountered this category.
ObjCCategoryDecl *MergeWithCategory
= ToInterface->FindCategoryDeclaration(Name.getAsIdentifierInfo());
@@ -3363,7 +3347,7 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
ObjCProtocolDecl *ToProto
= cast_or_null<ObjCProtocolDecl>(Importer.Import(*FromProto));
if (!ToProto)
- return 0;
+ return nullptr;
Protocols.push_back(ToProto);
ProtocolLocs.push_back(Importer.Import(*FromProtoLoc));
}
@@ -3385,8 +3369,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryDecl(ObjCCategoryDecl *D) {
= cast_or_null<ObjCCategoryImplDecl>(
Importer.Import(D->getImplementation()));
if (!Impl)
- return 0;
-
+ return nullptr;
+
ToCategory->setImplementation(Impl);
}
@@ -3441,8 +3425,8 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3451,9 +3435,9 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
- ObjCProtocolDecl *MergeWithProtocol = 0;
+ ObjCProtocolDecl *MergeWithProtocol = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3469,7 +3453,7 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
ToProto = ObjCProtocolDecl::Create(Importer.getToContext(), DC,
Name.getAsIdentifierInfo(), Loc,
Importer.Import(D->getAtStartLoc()),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
ToProto->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToProto);
}
@@ -3477,8 +3461,8 @@ Decl *ASTNodeImporter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
Importer.Imported(D, ToProto);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToProto))
- return 0;
-
+ return nullptr;
+
return ToProto;
}
@@ -3558,12 +3542,8 @@ bool ASTNodeImporter::ImportDefinition(ObjCInterfaceDecl *From,
// Import categories. When the categories themselves are imported, they'll
// hook themselves into this interface.
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = From->known_categories_begin(),
- CatEnd = From->known_categories_end();
- Cat != CatEnd; ++Cat) {
- Importer.Import(*Cat);
- }
+ for (auto *Cat : From->known_categories())
+ Importer.Import(Cat);
// If we have an @implementation, import it as well.
if (From->getImplementation()) {
@@ -3590,8 +3570,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3600,10 +3580,10 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Look for an existing interface with the same name.
- ObjCInterfaceDecl *MergeWithIface = 0;
+ ObjCInterfaceDecl *MergeWithIface = nullptr;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->localUncachedLookup(Name, FoundDecls);
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
@@ -3620,7 +3600,7 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getAtStartLoc()),
Name.getAsIdentifierInfo(),
- /*PrevDecl=*/0,Loc,
+ /*PrevDecl=*/nullptr, Loc,
D->isImplicitInterfaceDecl());
ToIface->setLexicalDeclContext(LexicalDC);
LexicalDC->addDeclInternal(ToIface);
@@ -3628,8 +3608,8 @@ Decl *ASTNodeImporter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
Importer.Imported(D, ToIface);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, ToIface))
- return 0;
-
+ return nullptr;
+
return ToIface;
}
@@ -3637,14 +3617,14 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
ObjCCategoryDecl *Category = cast_or_null<ObjCCategoryDecl>(
Importer.Import(D->getCategoryDecl()));
if (!Category)
- return 0;
-
+ return nullptr;
+
ObjCCategoryImplDecl *ToImpl = Category->getImplementation();
if (!ToImpl) {
DeclContext *DC = Importer.ImportContext(D->getDeclContext());
if (!DC)
- return 0;
-
+ return nullptr;
+
SourceLocation CategoryNameLoc = Importer.Import(D->getCategoryNameLoc());
ToImpl = ObjCCategoryImplDecl::Create(Importer.getToContext(), DC,
Importer.Import(D->getIdentifier()),
@@ -3657,8 +3637,8 @@ Decl *ASTNodeImporter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
-
+ return nullptr;
+
ToImpl->setLexicalDeclContext(LexicalDC);
}
@@ -3676,15 +3656,15 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
ObjCInterfaceDecl *Iface = cast_or_null<ObjCInterfaceDecl>(
Importer.Import(D->getClassInterface()));
if (!Iface)
- return 0;
+ return nullptr;
// Import the superclass, if any.
- ObjCInterfaceDecl *Super = 0;
+ ObjCInterfaceDecl *Super = nullptr;
if (D->getSuperClass()) {
Super = cast_or_null<ObjCInterfaceDecl>(
Importer.Import(D->getSuperClass()));
if (!Super)
- return 0;
+ return nullptr;
}
ObjCImplementationDecl *Impl = Iface->getImplementation();
@@ -3704,7 +3684,7 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
DeclContext *LexicalDC
= Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
Impl->setLexicalDeclContext(LexicalDC);
}
@@ -3717,28 +3697,29 @@ Decl *ASTNodeImporter::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
// Verify that the existing @implementation has the same superclass.
if ((Super && !Impl->getSuperClass()) ||
(!Super && Impl->getSuperClass()) ||
- (Super && Impl->getSuperClass() &&
- !declaresSameEntity(Super->getCanonicalDecl(), Impl->getSuperClass()))) {
- Importer.ToDiag(Impl->getLocation(),
- diag::err_odr_objc_superclass_inconsistent)
- << Iface->getDeclName();
- // FIXME: It would be nice to have the location of the superclass
- // below.
- if (Impl->getSuperClass())
- Importer.ToDiag(Impl->getLocation(),
+ (Super && Impl->getSuperClass() &&
+ !declaresSameEntity(Super->getCanonicalDecl(),
+ Impl->getSuperClass()))) {
+ Importer.ToDiag(Impl->getLocation(),
+ diag::err_odr_objc_superclass_inconsistent)
+ << Iface->getDeclName();
+ // FIXME: It would be nice to have the location of the superclass
+ // below.
+ if (Impl->getSuperClass())
+ Importer.ToDiag(Impl->getLocation(),
+ diag::note_odr_objc_superclass)
+ << Impl->getSuperClass()->getDeclName();
+ else
+ Importer.ToDiag(Impl->getLocation(),
+ diag::note_odr_objc_missing_superclass);
+ if (D->getSuperClass())
+ Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_superclass)
- << Impl->getSuperClass()->getDeclName();
- else
- Importer.ToDiag(Impl->getLocation(),
+ << D->getSuperClass()->getDeclName();
+ else
+ Importer.FromDiag(D->getLocation(),
diag::note_odr_objc_missing_superclass);
- if (D->getSuperClass())
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_superclass)
- << D->getSuperClass()->getDeclName();
- else
- Importer.FromDiag(D->getLocation(),
- diag::note_odr_objc_missing_superclass);
- return 0;
+ return nullptr;
}
}
@@ -3754,7 +3735,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// Check whether we have already imported this property.
SmallVector<NamedDecl *, 2> FoundDecls;
@@ -3769,7 +3750,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
<< Name << D->getType() << FoundProp->getType();
Importer.ToDiag(FoundProp->getLocation(), diag::note_odr_value_here)
<< FoundProp->getType();
- return 0;
+ return nullptr;
}
// FIXME: Check property attributes, getters, setters, etc.?
@@ -3783,7 +3764,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
// Import the type.
TypeSourceInfo *T = Importer.Import(D->getTypeSourceInfo());
if (!T)
- return 0;
+ return nullptr;
// Create the new property.
ObjCPropertyDecl *ToProperty
@@ -3815,31 +3796,31 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
ObjCPropertyDecl *Property = cast_or_null<ObjCPropertyDecl>(
Importer.Import(D->getPropertyDecl()));
if (!Property)
- return 0;
+ return nullptr;
DeclContext *DC = Importer.ImportContext(D->getDeclContext());
if (!DC)
- return 0;
-
+ return nullptr;
+
// Import the lexical declaration context.
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
ObjCImplDecl *InImpl = dyn_cast<ObjCImplDecl>(LexicalDC);
if (!InImpl)
- return 0;
+ return nullptr;
// Import the ivar (for an @synthesize).
- ObjCIvarDecl *Ivar = 0;
+ ObjCIvarDecl *Ivar = nullptr;
if (D->getPropertyIvarDecl()) {
Ivar = cast_or_null<ObjCIvarDecl>(
Importer.Import(D->getPropertyIvarDecl()));
if (!Ivar)
- return 0;
+ return nullptr;
}
ObjCPropertyImplDecl *ToImpl
@@ -3868,7 +3849,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
diag::note_odr_objc_property_impl_kind)
<< D->getPropertyDecl()->getDeclName()
<< (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
- return 0;
+ return nullptr;
}
// For @synthesize, check that we have the same
@@ -3882,7 +3863,7 @@ Decl *ASTNodeImporter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) {
Importer.FromDiag(D->getPropertyIvarDeclLoc(),
diag::note_odr_objc_synthesize_ivar_here)
<< D->getPropertyIvarDecl()->getDeclName();
- return 0;
+ return nullptr;
}
// Merge the existing implementation with the new implementation.
@@ -3914,21 +3895,21 @@ ASTNodeImporter::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
// Import the type of this declaration.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
// Import type-source information.
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
if (D->getTypeSourceInfo() && !TInfo)
- return 0;
-
+ return nullptr;
+
// FIXME: Import default argument.
return NonTypeTemplateParmDecl::Create(Importer.getToContext(),
@@ -3944,8 +3925,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
// Import the name of this declaration.
DeclarationName Name = Importer.Import(D->getDeclName());
if (D->getDeclName() && !Name)
- return 0;
-
+ return nullptr;
+
// Import the location of this declaration.
SourceLocation Loc = Importer.Import(D->getLocation());
@@ -3953,8 +3934,8 @@ ASTNodeImporter::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
TemplateParameterList *TemplateParams
= ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
-
+ return nullptr;
+
// FIXME: Import default argument.
return TemplateTemplateParmDecl::Create(Importer.getToContext(),
@@ -3975,8 +3956,8 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Decl *ImportedDef
= Importer.Import(Definition->getDescribedClassTemplate());
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -3985,8 +3966,8 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
-
+ return nullptr;
+
// We may already have a template of the same name; try to find and match it.
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
@@ -4019,7 +4000,7 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
}
if (!Name)
- return 0;
+ return nullptr;
}
CXXRecordDecl *DTemplated = D->getTemplatedDecl();
@@ -4039,12 +4020,12 @@ Decl *ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
TemplateParameterList *TemplateParams
= ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
-
+ return nullptr;
+
ClassTemplateDecl *D2 = ClassTemplateDecl::Create(Importer.getToContext(), DC,
Loc, Name, TemplateParams,
D2Templated,
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
D2Templated->setDescribedClassTemplate(D2);
D2->setAccess(D->getAccess());
@@ -4072,8 +4053,8 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
-
+ return nullptr;
+
return Importer.Imported(D, ImportedDef);
}
@@ -4081,18 +4062,18 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
= cast_or_null<ClassTemplateDecl>(Importer.Import(
D->getSpecializedTemplate()));
if (!ClassTemplate)
- return 0;
-
+ return nullptr;
+
// Import the context of this declaration.
DeclContext *DC = ClassTemplate->getDeclContext();
if (!DC)
- return 0;
-
+ return nullptr;
+
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
// Import the location of this declaration.
@@ -4104,13 +4085,12 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
if (ImportTemplateArguments(D->getTemplateArgs().data(),
D->getTemplateArgs().size(),
TemplateArgs))
- return 0;
-
+ return nullptr;
+
// Try to find an existing specialization with these template arguments.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
ClassTemplateSpecializationDecl *D2
- = ClassTemplate->findSpecialization(TemplateArgs.data(),
- TemplateArgs.size(), InsertPos);
+ = ClassTemplate->findSpecialization(TemplateArgs, InsertPos);
if (D2) {
// We already have a class template specialization with these template
// arguments.
@@ -4133,7 +4113,7 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
ClassTemplate,
TemplateArgs.data(),
TemplateArgs.size(),
- /*PrevDecl=*/0);
+ /*PrevDecl=*/nullptr);
D2->setSpecializationKind(D->getSpecializationKind());
// Add this specialization to the class template.
@@ -4149,8 +4129,8 @@ Decl *ASTNodeImporter::VisitClassTemplateSpecializationDecl(
Importer.Imported(D, D2);
if (D->isCompleteDefinition() && ImportDefinition(D, D2))
- return 0;
-
+ return nullptr;
+
return D2;
}
@@ -4164,7 +4144,7 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
if (Definition && Definition != D->getTemplatedDecl()) {
Decl *ImportedDef = Importer.Import(Definition->getDescribedVarTemplate());
if (!ImportedDef)
- return 0;
+ return nullptr;
return Importer.Imported(D, ImportedDef);
}
@@ -4174,7 +4154,7 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
DeclarationName Name;
SourceLocation Loc;
if (ImportDeclParts(D, DC, LexicalDC, Name, Loc))
- return 0;
+ return nullptr;
// We may already have a template of the same name; try to find and match it.
assert(!DC->isFunctionOrMethod() &&
@@ -4206,14 +4186,14 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
}
if (!Name)
- return 0;
+ return nullptr;
VarDecl *DTemplated = D->getTemplatedDecl();
// Import the type.
QualType T = Importer.Import(DTemplated->getType());
if (T.isNull())
- return 0;
+ return nullptr;
// Create the declaration that is being templated.
SourceLocation StartLoc = Importer.Import(DTemplated->getLocStart());
@@ -4231,17 +4211,16 @@ Decl *ASTNodeImporter::VisitVarTemplateDecl(VarTemplateDecl *D) {
// Merge the initializer.
if (ImportDefinition(DTemplated, D2Templated))
- return 0;
+ return nullptr;
// Create the variable template declaration itself.
TemplateParameterList *TemplateParams =
ImportTemplateParameterList(D->getTemplateParameters());
if (!TemplateParams)
- return 0;
+ return nullptr;
VarTemplateDecl *D2 = VarTemplateDecl::Create(
- Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated,
- /*PrevDecl=*/0);
+ Importer.getToContext(), DC, Loc, Name, TemplateParams, D2Templated);
D2Templated->setDescribedVarTemplate(D2);
D2->setAccess(D->getAccess());
@@ -4269,7 +4248,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
if (Definition && Definition != D) {
Decl *ImportedDef = Importer.Import(Definition);
if (!ImportedDef)
- return 0;
+ return nullptr;
return Importer.Imported(D, ImportedDef);
}
@@ -4277,18 +4256,18 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
VarTemplateDecl *VarTemplate = cast_or_null<VarTemplateDecl>(
Importer.Import(D->getSpecializedTemplate()));
if (!VarTemplate)
- return 0;
+ return nullptr;
// Import the context of this declaration.
DeclContext *DC = VarTemplate->getDeclContext();
if (!DC)
- return 0;
+ return nullptr;
DeclContext *LexicalDC = DC;
if (D->getDeclContext() != D->getLexicalDeclContext()) {
LexicalDC = Importer.ImportContext(D->getLexicalDeclContext());
if (!LexicalDC)
- return 0;
+ return nullptr;
}
// Import the location of this declaration.
@@ -4299,12 +4278,12 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
SmallVector<TemplateArgument, 2> TemplateArgs;
if (ImportTemplateArguments(D->getTemplateArgs().data(),
D->getTemplateArgs().size(), TemplateArgs))
- return 0;
+ return nullptr;
// Try to find an existing specialization with these template arguments.
- void *InsertPos = 0;
+ void *InsertPos = nullptr;
VarTemplateSpecializationDecl *D2 = VarTemplate->findSpecialization(
- TemplateArgs.data(), TemplateArgs.size(), InsertPos);
+ TemplateArgs, InsertPos);
if (D2) {
// We already have a variable template specialization with these template
// arguments.
@@ -4325,7 +4304,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
// Import the type.
QualType T = Importer.Import(D->getType());
if (T.isNull())
- return 0;
+ return nullptr;
TypeSourceInfo *TInfo = Importer.Import(D->getTypeSourceInfo());
// Create a new specialization.
@@ -4348,7 +4327,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
Importer.Imported(D, D2);
if (D->isThisDeclarationADefinition() && ImportDefinition(D, D2))
- return 0;
+ return nullptr;
return D2;
}
@@ -4360,7 +4339,7 @@ Decl *ASTNodeImporter::VisitVarTemplateSpecializationDecl(
Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
Importer.FromDiag(S->getLocStart(), diag::err_unsupported_ast_node)
<< S->getStmtClassName();
- return 0;
+ return nullptr;
}
//----------------------------------------------------------------------------
@@ -4369,24 +4348,24 @@ Stmt *ASTNodeImporter::VisitStmt(Stmt *S) {
Expr *ASTNodeImporter::VisitExpr(Expr *E) {
Importer.FromDiag(E->getLocStart(), diag::err_unsupported_ast_node)
<< E->getStmtClassName();
- return 0;
+ return nullptr;
}
Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
ValueDecl *ToD = cast_or_null<ValueDecl>(Importer.Import(E->getDecl()));
if (!ToD)
- return 0;
+ return nullptr;
- NamedDecl *FoundD = 0;
+ NamedDecl *FoundD = nullptr;
if (E->getDecl() != E->getFoundDecl()) {
FoundD = cast_or_null<NamedDecl>(Importer.Import(E->getFoundDecl()));
if (!FoundD)
- return 0;
+ return nullptr;
}
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
Importer.Import(E->getQualifierLoc()),
@@ -4396,7 +4375,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
- /*FIXME:TemplateArgs=*/0);
+ /*FIXME:TemplateArgs=*/nullptr);
if (E->hadMultipleCandidates())
DRE->setHadMultipleCandidates(true);
return DRE;
@@ -4405,7 +4384,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
return IntegerLiteral::Create(Importer.getToContext(),
E->getValue(), T,
@@ -4415,8 +4394,8 @@ Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {
Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) CharacterLiteral(E->getValue(),
E->getKind(), T,
Importer.Import(E->getLocation()));
@@ -4425,8 +4404,8 @@ Expr *ASTNodeImporter::VisitCharacterLiteral(CharacterLiteral *E) {
Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext())
ParenExpr(Importer.Import(E->getLParen()),
Importer.Import(E->getRParen()),
@@ -4436,12 +4415,12 @@ Expr *ASTNodeImporter::VisitParenExpr(ParenExpr *E) {
Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(),
T, E->getValueKind(),
E->getObjectKind(),
@@ -4455,8 +4434,8 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
if (E->isArgumentType()) {
TypeSourceInfo *TInfo = Importer.Import(E->getArgumentTypeInfo());
if (!TInfo)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
TInfo, ResultType,
Importer.Import(E->getOperatorLoc()),
@@ -4465,8 +4444,8 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
Expr *SubExpr = Importer.Import(E->getArgumentExpr());
if (!SubExpr)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) UnaryExprOrTypeTraitExpr(E->getKind(),
SubExpr, ResultType,
Importer.Import(E->getOperatorLoc()),
@@ -4476,16 +4455,16 @@ Expr *ASTNodeImporter::VisitUnaryExprOrTypeTraitExpr(
Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *LHS = Importer.Import(E->getLHS());
if (!LHS)
- return 0;
-
+ return nullptr;
+
Expr *RHS = Importer.Import(E->getRHS());
if (!RHS)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(),
T, E->getValueKind(),
E->getObjectKind(),
@@ -4496,24 +4475,24 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) {
Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
QualType CompLHSType = Importer.Import(E->getComputationLHSType());
if (CompLHSType.isNull())
- return 0;
-
+ return nullptr;
+
QualType CompResultType = Importer.Import(E->getComputationResultType());
if (CompResultType.isNull())
- return 0;
-
+ return nullptr;
+
Expr *LHS = Importer.Import(E->getLHS());
if (!LHS)
- return 0;
-
+ return nullptr;
+
Expr *RHS = Importer.Import(E->getRHS());
if (!RHS)
- return 0;
-
+ return nullptr;
+
return new (Importer.getToContext())
CompoundAssignOperator(LHS, RHS, E->getOpcode(),
T, E->getValueKind(),
@@ -4533,15 +4512,15 @@ static bool ImportCastPath(CastExpr *E, CXXCastPath &Path) {
Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
+ return nullptr;
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
+ return nullptr;
CXXCastPath BasePath;
if (ImportCastPath(E, BasePath))
- return 0;
+ return nullptr;
return ImplicitCastExpr::Create(Importer.getToContext(), T, E->getCastKind(),
SubExpr, &BasePath, E->getValueKind());
@@ -4550,19 +4529,19 @@ Expr *ASTNodeImporter::VisitImplicitCastExpr(ImplicitCastExpr *E) {
Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
- return 0;
-
+ return nullptr;
+
Expr *SubExpr = Importer.Import(E->getSubExpr());
if (!SubExpr)
- return 0;
+ return nullptr;
TypeSourceInfo *TInfo = Importer.Import(E->getTypeInfoAsWritten());
if (!TInfo && E->getTypeInfoAsWritten())
- return 0;
-
+ return nullptr;
+
CXXCastPath BasePath;
if (ImportCastPath(E, BasePath))
- return 0;
+ return nullptr;
return CStyleCastExpr::Create(Importer.getToContext(), T,
E->getValueKind(), E->getCastKind(),
@@ -4616,7 +4595,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
// on the type and a single location. Implement a real version of this.
QualType T = Import(FromTSI->getType());
if (T.isNull())
- return 0;
+ return nullptr;
return ToContext.getTrivialTypeSourceInfo(T,
FromTSI->getTypeLoc().getLocStart());
@@ -4624,7 +4603,7 @@ TypeSourceInfo *ASTImporter::Import(TypeSourceInfo *FromTSI) {
Decl *ASTImporter::Import(Decl *FromD) {
if (!FromD)
- return 0;
+ return nullptr;
ASTNodeImporter Importer(*this);
@@ -4639,8 +4618,8 @@ Decl *ASTImporter::Import(Decl *FromD) {
// Import the type
Decl *ToD = Importer.Visit(FromD);
if (!ToD)
- return 0;
-
+ return nullptr;
+
// Record the imported declaration.
ImportedDecls[FromD] = ToD;
@@ -4675,8 +4654,8 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
DeclContext *ToDC = cast_or_null<DeclContext>(Import(cast<Decl>(FromDC)));
if (!ToDC)
- return 0;
-
+ return nullptr;
+
// When we're using a record/enum/Objective-C class/protocol as a context, we
// need it to have a definition.
if (RecordDecl *ToRecord = dyn_cast<RecordDecl>(ToDC)) {
@@ -4726,14 +4705,14 @@ DeclContext *ASTImporter::ImportContext(DeclContext *FromDC) {
Expr *ASTImporter::Import(Expr *FromE) {
if (!FromE)
- return 0;
+ return nullptr;
return cast_or_null<Expr>(Import(cast<Stmt>(FromE)));
}
Stmt *ASTImporter::Import(Stmt *FromS) {
if (!FromS)
- return 0;
+ return nullptr;
// Check whether we've already imported this declaration.
llvm::DenseMap<Stmt *, Stmt *>::iterator Pos = ImportedStmts.find(FromS);
@@ -4744,8 +4723,8 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
ASTNodeImporter Importer(*this);
Stmt *ToS = Importer.Visit(FromS);
if (!ToS)
- return 0;
-
+ return nullptr;
+
// Record the imported declaration.
ImportedStmts[FromS] = ToS;
return ToS;
@@ -4753,7 +4732,7 @@ Stmt *ASTImporter::Import(Stmt *FromS) {
NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (!FromNNS)
- return 0;
+ return nullptr;
NestedNameSpecifier *prefix = Import(FromNNS->getPrefix());
@@ -4762,21 +4741,21 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
if (IdentifierInfo *II = Import(FromNNS->getAsIdentifier())) {
return NestedNameSpecifier::Create(ToContext, prefix, II);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::Namespace:
if (NamespaceDecl *NS =
cast<NamespaceDecl>(Import(FromNNS->getAsNamespace()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NS);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::NamespaceAlias:
if (NamespaceAliasDecl *NSAD =
cast<NamespaceAliasDecl>(Import(FromNNS->getAsNamespaceAlias()))) {
return NestedNameSpecifier::Create(ToContext, prefix, NSAD);
}
- return 0;
+ return nullptr;
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
@@ -4791,7 +4770,7 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
bTemplate, T.getTypePtr());
}
}
- return 0;
+ return nullptr;
}
llvm_unreachable("Invalid nested name specifier kind");
@@ -4943,8 +4922,7 @@ FileID ASTImporter::Import(FileID FromID) {
llvm::MemoryBuffer *ToBuf
= llvm::MemoryBuffer::getMemBufferCopy(FromBuf->getBuffer(),
FromBuf->getBufferIdentifier());
- ToID = ToSM.createFileIDForMemBuffer(ToBuf,
- FromSLoc.getFile().getFileCharacteristic());
+ ToID = ToSM.createFileID(ToBuf, FromSLoc.getFile().getFileCharacteristic());
}
@@ -5054,7 +5032,7 @@ DeclarationName ASTImporter::Import(DeclarationName FromName) {
IdentifierInfo *ASTImporter::Import(const IdentifierInfo *FromId) {
if (!FromId)
- return 0;
+ return nullptr;
return &ToContext.Idents.get(FromId->getName());
}
diff --git a/lib/AST/ASTTypeTraits.cpp b/lib/AST/ASTTypeTraits.cpp
index ae47ea98882b..baa8e48779a2 100644
--- a/lib/AST/ASTTypeTraits.cpp
+++ b/lib/AST/ASTTypeTraits.cpp
@@ -39,18 +39,24 @@ const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
#include "clang/AST/TypeNodes.def"
};
-bool ASTNodeKind::isBaseOf(ASTNodeKind Other) const {
- return isBaseOf(KindId, Other.KindId);
+bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
+ return isBaseOf(KindId, Other.KindId, Distance);
}
bool ASTNodeKind::isSame(ASTNodeKind Other) const {
return KindId != NKI_None && KindId == Other.KindId;
}
-bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived) {
+bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
+ unsigned *Distance) {
if (Base == NKI_None || Derived == NKI_None) return false;
- while (Derived != Base && Derived != NKI_None)
+ unsigned Dist = 0;
+ while (Derived != Base && Derived != NKI_None) {
Derived = AllKindInfo[Derived].ParentId;
+ ++Dist;
+ }
+ if (Distance)
+ *Distance = Dist;
return Derived == Base;
}
@@ -71,7 +77,7 @@ void DynTypedNode::print(llvm::raw_ostream &OS,
else if (const Decl *D = get<Decl>())
D->print(OS, PP);
else if (const Stmt *S = get<Stmt>())
- S->printPretty(OS, 0, PP);
+ S->printPretty(OS, nullptr, PP);
else if (const Type *T = get<Type>())
QualType(T, 0).print(OS, PP);
else
diff --git a/lib/AST/AttrImpl.cpp b/lib/AST/AttrImpl.cpp
index 7af3c8b16263..0bf6bcd9092e 100644
--- a/lib/AST/AttrImpl.cpp
+++ b/lib/AST/AttrImpl.cpp
@@ -24,6 +24,4 @@ void InheritableAttr::anchor() { }
void InheritableParamAttr::anchor() { }
-void MSInheritanceAttr::anchor() { }
-
#include "clang/AST/AttrImpl.inc"
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 461e8b3ac18e..9006be64f73f 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -57,29 +57,8 @@ add_clang_library(clangAST
TypePrinter.cpp
VTableBuilder.cpp
VTTBuilder.cpp
- )
-
-add_dependencies(clangAST
- ClangARMNeon
- ClangAttrClasses
- ClangAttrList
- ClangAttrImpl
- ClangAttrDump
- ClangCommentCommandInfo
- ClangCommentCommandList
- ClangCommentNodes
- ClangCommentHTMLTags
- ClangCommentHTMLTagsProperties
- ClangCommentHTMLNamedCharacterReferences
- ClangDeclNodes
- ClangDiagnosticAST
- ClangDiagnosticComment
- ClangDiagnosticCommon
- ClangDiagnosticSema
- ClangStmtNodes
- )
-target_link_libraries(clangAST
+ LINK_LIBS
clangBasic
clangLex
)
diff --git a/lib/AST/CXXABI.h b/lib/AST/CXXABI.h
index 89203f18ca77..12b929b88db0 100644
--- a/lib/AST/CXXABI.h
+++ b/lib/AST/CXXABI.h
@@ -44,7 +44,6 @@ public:
};
/// Creates an instance of a C++ ABI class.
-CXXABI *CreateARMCXXABI(ASTContext &Ctx);
CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
}
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index b51014b7428f..6e80ee7c28a1 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -35,16 +35,12 @@ void CXXBasePaths::ComputeDeclsFound() {
std::copy(Decls.begin(), Decls.end(), DeclsFound);
}
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_begin() {
+CXXBasePaths::decl_range CXXBasePaths::found_decls() {
if (NumDeclsFound == 0)
ComputeDeclsFound();
- return DeclsFound;
-}
-CXXBasePaths::decl_iterator CXXBasePaths::found_decls_end() {
- if (NumDeclsFound == 0)
- ComputeDeclsFound();
- return DeclsFound + NumDeclsFound;
+ return decl_range(decl_iterator(DeclsFound),
+ decl_iterator(DeclsFound + NumDeclsFound));
}
/// isAmbiguous - Determines whether the set of paths provided is
@@ -62,7 +58,7 @@ void CXXBasePaths::clear() {
Paths.clear();
ClassSubobjects.clear();
ScratchPath.clear();
- DetectedVirtual = 0;
+ DetectedVirtual = nullptr;
}
/// @brief Swaps the contents of this CXXBasePaths structure with the
@@ -141,9 +137,8 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
const CXXRecordDecl *Record = this;
bool AllMatches = true;
while (true) {
- for (CXXRecordDecl::base_class_const_iterator
- I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
- const RecordType *Ty = I->getType()->getAs<RecordType>();
+ for (const auto &I : Record->bases()) {
+ const RecordType *Ty = I.getType()->getAs<RecordType>();
if (!Ty) {
if (AllowShortCircuit) return false;
AllMatches = false;
@@ -186,14 +181,11 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
AccessSpecifier AccessToHere = ScratchPath.Access;
bool IsFirstStep = ScratchPath.empty();
- for (CXXRecordDecl::base_class_const_iterator BaseSpec = Record->bases_begin(),
- BaseSpecEnd = Record->bases_end();
- BaseSpec != BaseSpecEnd;
- ++BaseSpec) {
+ for (const auto &BaseSpec : Record->bases()) {
// Find the record of the base class subobjects for this type.
- QualType BaseType = Context.getCanonicalType(BaseSpec->getType())
- .getUnqualifiedType();
-
+ QualType BaseType =
+ Context.getCanonicalType(BaseSpec.getType()).getUnqualifiedType();
+
// C++ [temp.dep]p3:
// In the definition of a class template or a member of a class template,
// if a base class of the class template depends on a template-parameter,
@@ -208,10 +200,10 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
std::pair<bool, unsigned>& Subobjects = ClassSubobjects[BaseType];
bool VisitBase = true;
bool SetVirtual = false;
- if (BaseSpec->isVirtual()) {
+ if (BaseSpec.isVirtual()) {
VisitBase = !Subobjects.first;
Subobjects.first = true;
- if (isDetectingVirtual() && DetectedVirtual == 0) {
+ if (isDetectingVirtual() && DetectedVirtual == nullptr) {
// If this is the first virtual we find, remember it. If it turns out
// there is no base path here, we'll reset it later.
DetectedVirtual = BaseType->getAs<RecordType>();
@@ -223,9 +215,9 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
if (isRecordingPaths()) {
// Add this base specifier to the current path.
CXXBasePathElement Element;
- Element.Base = &*BaseSpec;
+ Element.Base = &BaseSpec;
Element.Class = Record;
- if (BaseSpec->isVirtual())
+ if (BaseSpec.isVirtual())
Element.SubobjectNumber = 0;
else
Element.SubobjectNumber = Subobjects.second;
@@ -247,16 +239,16 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// 3. Otherwise, overall access is determined by the most restrictive
// access in the sequence.
if (IsFirstStep)
- ScratchPath.Access = BaseSpec->getAccessSpecifier();
+ ScratchPath.Access = BaseSpec.getAccessSpecifier();
else
ScratchPath.Access = CXXRecordDecl::MergeAccess(AccessToHere,
- BaseSpec->getAccessSpecifier());
+ BaseSpec.getAccessSpecifier());
}
// Track whether there's a path involving this specific base.
bool FoundPathThroughBase = false;
- if (BaseMatches(BaseSpec, ScratchPath, UserData)) {
+ if (BaseMatches(&BaseSpec, ScratchPath, UserData)) {
// We've found a path that terminates at this base.
FoundPath = FoundPathThroughBase = true;
if (isRecordingPaths()) {
@@ -269,7 +261,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
}
} else if (VisitBase) {
CXXRecordDecl *BaseRecord
- = cast<CXXRecordDecl>(BaseSpec->getType()->castAs<RecordType>()
+ = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
->getDecl());
if (lookupInBases(Context, BaseRecord, BaseMatches, UserData)) {
// C++ [class.member.lookup]p2:
@@ -294,7 +286,7 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
// If we set a virtual earlier, and this isn't a path, forget it again.
if (SetVirtual && !FoundPathThroughBase) {
- DetectedVirtual = 0;
+ DetectedVirtual = nullptr;
}
}
@@ -333,7 +325,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
for (CXXBasePath::iterator PE = P->begin(), PEEnd = P->end();
PE != PEEnd && !Hidden; ++PE) {
if (PE->Base->isVirtual()) {
- CXXRecordDecl *VBase = 0;
+ CXXRecordDecl *VBase = nullptr;
if (const RecordType *Record = PE->Base->getType()->getAs<RecordType>())
VBase = cast<CXXRecordDecl>(Record->getDecl());
if (!VBase)
@@ -347,7 +339,7 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback *BaseMatches,
HidingPEnd = Paths.end();
HidingP != HidingPEnd;
++HidingP) {
- CXXRecordDecl *HidingClass = 0;
+ CXXRecordDecl *HidingClass = nullptr;
if (const RecordType *Record
= HidingP->back().Base->getType()->getAs<RecordType>())
HidingClass = cast<CXXRecordDecl>(Record->getDecl());
@@ -501,14 +493,13 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
SubobjectNumber
= ++SubobjectCount[cast<CXXRecordDecl>(RD->getCanonicalDecl())];
- for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(),
- BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) {
- if (const RecordType *RT = Base->getType()->getAs<RecordType>()) {
+ for (const auto &Base : RD->bases()) {
+ if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
if (!BaseDecl->isPolymorphic())
continue;
- if (Overriders.empty() && !Base->isVirtual()) {
+ if (Overriders.empty() && !Base.isVirtual()) {
// There are no other overriders of virtual member functions,
// so let the base class fill in our overriders for us.
Collect(BaseDecl, false, InVirtualSubobject, Overriders);
@@ -522,7 +513,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
// its base classes) more than once.
CXXFinalOverriderMap ComputedBaseOverriders;
CXXFinalOverriderMap *BaseOverriders = &ComputedBaseOverriders;
- if (Base->isVirtual()) {
+ if (Base.isVirtual()) {
CXXFinalOverriderMap *&MyVirtualOverriders = VirtualOverriders[BaseDecl];
BaseOverriders = MyVirtualOverriders;
if (!MyVirtualOverriders) {
@@ -551,10 +542,7 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
}
}
- for (CXXRecordDecl::method_iterator M = RD->method_begin(),
- MEnd = RD->method_end();
- M != MEnd;
- ++M) {
+ for (auto *M : RD->methods()) {
// We only care about virtual methods.
if (!M->isVirtual())
continue;
@@ -637,7 +625,7 @@ FinalOverriderCollector::~FinalOverriderCollector() {
void
CXXRecordDecl::getFinalOverriders(CXXFinalOverriderMap &FinalOverriders) const {
FinalOverriderCollector Collector;
- Collector.Collect(this, false, 0, FinalOverriders);
+ Collector.Collect(this, false, nullptr, FinalOverriders);
// Weed out any final overriders that come from virtual base class
// subobjects that were hidden by other subobjects along any path.
@@ -702,13 +690,12 @@ AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context,
if (Layout.isPrimaryBaseVirtual())
Bases.insert(Layout.getPrimaryBase());
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const auto &I : RD->bases()) {
+ assert(!I.getType()->isDependentType() &&
"Cannot get indirect primary bases for class with dependent bases.");
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
// Only bases with virtual bases participate in computing the
// indirect primary virtual base classes.
@@ -725,13 +712,12 @@ CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const {
if (!getNumVBases())
return;
- for (CXXRecordDecl::base_class_const_iterator I = bases_begin(),
- E = bases_end(); I != E; ++I) {
- assert(!I->getType()->isDependentType() &&
+ for (const auto &I : bases()) {
+ assert(!I.getType()->isDependentType() &&
"Cannot get indirect primary bases for class with dependent bases.");
const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
// Only bases with virtual bases participate in computing the
// indirect primary virtual base classes.
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index f24a23d34c57..4f433467f9bc 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -136,7 +136,7 @@ void DeclInfo::fill() {
IsInstanceMethod = false;
IsClassMethod = false;
ParamVars = None;
- TemplateParameters = NULL;
+ TemplateParameters = nullptr;
if (!CommentDecl) {
// If there is no declaration, the defaults is our only guess.
@@ -159,7 +159,7 @@ void DeclInfo::fill() {
Kind = FunctionKind;
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
FD->getNumParams());
- ResultType = FD->getResultType();
+ ReturnType = FD->getReturnType();
unsigned NumLists = FD->getNumTemplateParameterLists();
if (NumLists != 0) {
TemplateKind = TemplateSpecialization;
@@ -180,7 +180,7 @@ void DeclInfo::fill() {
Kind = FunctionKind;
ParamVars = ArrayRef<const ParmVarDecl *>(MD->param_begin(),
MD->param_size());
- ResultType = MD->getResultType();
+ ReturnType = MD->getReturnType();
IsObjCMethod = true;
IsInstanceMethod = MD->isInstanceMethod();
IsClassMethod = !IsInstanceMethod;
@@ -193,7 +193,7 @@ void DeclInfo::fill() {
const FunctionDecl *FD = FTD->getTemplatedDecl();
ParamVars = ArrayRef<const ParmVarDecl *>(FD->param_begin(),
FD->getNumParams());
- ResultType = FD->getResultType();
+ ReturnType = FD->getReturnType();
TemplateParameters = FTD->getTemplateParameters();
break;
}
@@ -251,6 +251,16 @@ void DeclInfo::fill() {
TL = PointerTL.getPointeeLoc().getUnqualifiedLoc();
continue;
}
+ // Look through reference types.
+ if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>()) {
+ TL = ReferenceTL.getPointeeLoc().getUnqualifiedLoc();
+ continue;
+ }
+ // Look through adjusted types.
+ if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>()) {
+ TL = ATL.getOriginalLoc();
+ continue;
+ }
if (BlockPointerTypeLoc BlockPointerTL =
TL.getAs<BlockPointerTypeLoc>()) {
TL = BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
@@ -261,13 +271,39 @@ void DeclInfo::fill() {
TL = MemberPointerTL.getPointeeLoc().getUnqualifiedLoc();
continue;
}
+ if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>()) {
+ TL = ETL.getNamedTypeLoc();
+ continue;
+ }
// Is this a typedef for a function type?
if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
Kind = FunctionKind;
ArrayRef<ParmVarDecl *> Params = FTL.getParams();
ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
Params.size());
- ResultType = FTL.getResultLoc().getType();
+ ReturnType = FTL.getReturnLoc().getType();
+ break;
+ }
+ if (TemplateSpecializationTypeLoc STL =
+ TL.getAs<TemplateSpecializationTypeLoc>()) {
+ // If we have a typedef to a template specialization with exactly one
+ // template argument of a function type, this looks like std::function,
+ // boost::function, or other function wrapper. Treat these typedefs as
+ // functions.
+ if (STL.getNumArgs() != 1)
+ break;
+ TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0);
+ if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type)
+ break;
+ TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo();
+ TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc();
+ if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
+ Kind = FunctionKind;
+ ArrayRef<ParmVarDecl *> Params = FTL.getParams();
+ ParamVars = ArrayRef<const ParmVarDecl *>(Params.data(),
+ Params.size());
+ ReturnType = FTL.getReturnLoc().getType();
+ }
break;
}
break;
diff --git a/lib/AST/CommentCommandTraits.cpp b/lib/AST/CommentCommandTraits.cpp
index 01bd12e5fefa..a7b07a40c985 100644
--- a/lib/AST/CommentCommandTraits.cpp
+++ b/lib/AST/CommentCommandTraits.cpp
@@ -43,47 +43,42 @@ const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
return getRegisteredCommandInfo(CommandID);
}
-static void
-HelperTypoCorrectCommandInfo(SmallVectorImpl<const CommandInfo *> &BestCommand,
- StringRef Typo, const CommandInfo *Command) {
- const unsigned MaxEditDistance = 1;
- unsigned BestEditDistance = MaxEditDistance + 1;
- StringRef Name = Command->Name;
-
- unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
- if (MinPossibleEditDistance > 0 &&
- Typo.size() / MinPossibleEditDistance < 1)
- return;
- unsigned EditDistance = Typo.edit_distance(Name, true, MaxEditDistance);
- if (EditDistance > MaxEditDistance)
- return;
- if (EditDistance == BestEditDistance)
- BestCommand.push_back(Command);
- else if (EditDistance < BestEditDistance) {
- BestCommand.clear();
- BestCommand.push_back(Command);
- BestEditDistance = EditDistance;
- }
-}
-
const CommandInfo *
CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const {
- // single character command impostures, such as \t or \n must not go
+ // Single-character command impostures, such as \t or \n, should not go
// through the fixit logic.
if (Typo.size() <= 1)
- return NULL;
-
+ return nullptr;
+
+ // The maximum edit distance we're prepared to accept.
+ const unsigned MaxEditDistance = 1;
+
+ unsigned BestEditDistance = MaxEditDistance;
SmallVector<const CommandInfo *, 2> BestCommand;
-
- const int NumOfCommands = llvm::array_lengthof(Commands);
- for (int i = 0; i < NumOfCommands; i++)
- HelperTypoCorrectCommandInfo(BestCommand, Typo, &Commands[i]);
-
- for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i)
- if (!RegisteredCommands[i]->IsUnknownCommand)
- HelperTypoCorrectCommandInfo(BestCommand, Typo, RegisteredCommands[i]);
-
- return (BestCommand.size() != 1) ? NULL : BestCommand[0];
+
+ auto ConsiderCorrection = [&](const CommandInfo *Command) {
+ StringRef Name = Command->Name;
+
+ unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
+ if (MinPossibleEditDistance <= BestEditDistance) {
+ unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
+ if (EditDistance < BestEditDistance) {
+ BestEditDistance = EditDistance;
+ BestCommand.clear();
+ }
+ if (EditDistance == BestEditDistance)
+ BestCommand.push_back(Command);
+ }
+ };
+
+ for (const auto &Command : Commands)
+ ConsiderCorrection(&Command);
+
+ for (const auto *Command : RegisteredCommands)
+ if (!Command->IsUnknownCommand)
+ ConsiderCorrection(Command);
+
+ return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
}
CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
@@ -118,7 +113,7 @@ const CommandInfo *CommandTraits::getBuiltinCommandInfo(
unsigned CommandID) {
if (CommandID < llvm::array_lengthof(Commands))
return &Commands[CommandID];
- return NULL;
+ return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
@@ -127,7 +122,7 @@ const CommandInfo *CommandTraits::getRegisteredCommandInfo(
if (RegisteredCommands[i]->Name == Name)
return RegisteredCommands[i];
}
- return NULL;
+ return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp
index 01ed3ce80a66..792a8320449b 100644
--- a/lib/AST/CommentLexer.cpp
+++ b/lib/AST/CommentLexer.cpp
@@ -268,6 +268,19 @@ const char *findCCommentEnd(const char *BufferPtr, const char *BufferEnd) {
} // unnamed namespace
+void Lexer::formTokenWithChars(Token &Result, const char *TokEnd,
+ tok::TokenKind Kind) {
+ const unsigned TokLen = TokEnd - BufferPtr;
+ Result.setLocation(getSourceLocation(BufferPtr));
+ Result.setKind(Kind);
+ Result.setLength(TokLen);
+#ifndef NDEBUG
+ Result.TextPtr = "<UNSET>";
+ Result.IntVal = 7;
+#endif
+ BufferPtr = TokEnd;
+}
+
void Lexer::lexCommentText(Token &T) {
assert(CommentState == LCS_InsideBCPLComment ||
CommentState == LCS_InsideCComment);
diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp
index 03e01015b954..cb37ec35f4d3 100644
--- a/lib/AST/CommentParser.cpp
+++ b/lib/AST/CommentParser.cpp
@@ -311,9 +311,9 @@ void Parser::parseBlockCommandArgs(BlockCommandComment *BC,
BlockCommandComment *Parser::parseBlockCommand() {
assert(Tok.is(tok::backslash_command) || Tok.is(tok::at_command));
- ParamCommandComment *PC = 0;
- TParamCommandComment *TPC = 0;
- BlockCommandComment *BC = 0;
+ ParamCommandComment *PC = nullptr;
+ TParamCommandComment *TPC = nullptr;
+ BlockCommandComment *BC = nullptr;
const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
CommandMarkerKind CommandMarker =
Tok.is(tok::backslash_command) ? CMK_Backslash : CMK_At;
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 1c6222f9ec02..12823c37dfc6 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -29,7 +29,8 @@ Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
DiagnosticsEngine &Diags, CommandTraits &Traits,
const Preprocessor *PP) :
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
- PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), HeaderfileCommand(NULL) {
+ PP(PP), ThisDeclInfo(nullptr), BriefCommand(nullptr),
+ HeaderfileCommand(nullptr) {
}
void Sema::setDecl(const Decl *D) {
@@ -68,8 +69,12 @@ void Sema::actOnBlockCommandFinish(BlockCommandComment *Command,
Command->setParagraph(Paragraph);
checkBlockCommandEmptyParagraph(Command);
checkBlockCommandDuplicate(Command);
- checkReturnsCommand(Command);
- checkDeprecatedCommand(Command);
+ if (ThisDeclInfo) {
+ // These checks only make sense if the comment is attached to a
+ // declaration.
+ checkReturnsCommand(Command);
+ checkDeprecatedCommand(Command);
+ }
}
ParamCommandComment *Sema::actOnParamCommandStart(
@@ -122,7 +127,7 @@ void Sema::checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment) {
<< (DiagSelect-1) << (DiagSelect-1)
<< Comment->getSourceRange();
}
-
+
void Sema::checkContainerDeclVerbatimLine(const BlockCommandComment *Comment) {
const CommandInfo *Info = Traits.getCommandInfo(Comment->getCommandID());
if (!Info->IsRecordLikeDeclarationCommand)
@@ -478,6 +483,7 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
if (isHTMLEndTagForbidden(TagName)) {
Diag(HET->getLocation(), diag::warn_doc_html_end_forbidden)
<< TagName << HET->getSourceRange();
+ HET->setIsMalformed();
return HET;
}
@@ -493,14 +499,19 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
if (!FoundOpen) {
Diag(HET->getLocation(), diag::warn_doc_html_end_unbalanced)
<< HET->getSourceRange();
+ HET->setIsMalformed();
return HET;
}
while (!HTMLOpenTags.empty()) {
- const HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+ HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
StringRef LastNotClosedTagName = HST->getTagName();
- if (LastNotClosedTagName == TagName)
+ if (LastNotClosedTagName == TagName) {
+ // If the start tag is malformed, end tag is malformed as well.
+ if (HST->isMalformed())
+ HET->setIsMalformed();
break;
+ }
if (isHTMLEndTagOptional(LastNotClosedTagName))
continue;
@@ -514,16 +525,18 @@ HTMLEndTagComment *Sema::actOnHTMLEndTag(SourceLocation LocBegin,
HET->getLocation(),
&CloseLineInvalid);
- if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine)
+ if (OpenLineInvalid || CloseLineInvalid || OpenLine == CloseLine) {
Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
<< HST->getTagName() << HET->getTagName()
<< HST->getSourceRange() << HET->getSourceRange();
- else {
+ HST->setIsMalformed();
+ } else {
Diag(HST->getLocation(), diag::warn_doc_html_start_end_mismatch)
<< HST->getTagName() << HET->getTagName()
<< HST->getSourceRange();
Diag(HET->getLocation(), diag::note_doc_html_end_tag)
<< HET->getSourceRange();
+ HST->setIsMalformed();
}
}
@@ -534,6 +547,18 @@ FullComment *Sema::actOnFullComment(
ArrayRef<BlockContentComment *> Blocks) {
FullComment *FC = new (Allocator) FullComment(Blocks, ThisDeclInfo);
resolveParamCommandIndexes(FC);
+
+ // Complain about HTML tags that are not closed.
+ while (!HTMLOpenTags.empty()) {
+ HTMLStartTagComment *HST = HTMLOpenTags.pop_back_val();
+ if (isHTMLEndTagOptional(HST->getTagName()))
+ continue;
+
+ Diag(HST->getLocation(), diag::warn_doc_html_missing_end_tag)
+ << HST->getTagName() << HST->getSourceRange();
+ HST->setIsMalformed();
+ }
+
return FC;
}
@@ -558,8 +583,11 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand)
return;
+
+ assert(ThisDeclInfo && "should not call this check on a bare comment");
+
if (isFunctionDecl()) {
- if (ThisDeclInfo->ResultType->isVoidType()) {
+ if (ThisDeclInfo->ReturnType->isVoidType()) {
unsigned DiagKind;
switch (ThisDeclInfo->CommentDecl->getKind()) {
default:
@@ -586,7 +614,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
}
else if (isObjCPropertyDecl())
return;
-
+
Diag(Command->getLocation(),
diag::warn_doc_returns_not_attached_to_a_function_decl)
<< Command->getCommandMarker()
@@ -596,7 +624,7 @@ void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
void Sema::checkBlockCommandDuplicate(const BlockCommandComment *Command) {
const CommandInfo *Info = Traits.getCommandInfo(Command->getCommandID());
- const BlockCommandComment *PrevCommand = NULL;
+ const BlockCommandComment *PrevCommand = nullptr;
if (Info->IsBriefCommand) {
if (!BriefCommand) {
BriefCommand = Command;
@@ -636,6 +664,8 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) {
if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand)
return;
+ assert(ThisDeclInfo && "should not call this check on a bare comment");
+
const Decl *D = ThisDeclInfo->CommentDecl;
if (!D)
return;
@@ -694,7 +724,7 @@ void Sema::resolveParamCommandIndexes(const FullComment *FC) {
SmallVector<ParamCommandComment *, 8> ParamVarDocs;
ArrayRef<const ParmVarDecl *> ParamVars = getParamVars();
- ParamVarDocs.resize(ParamVars.size(), NULL);
+ ParamVarDocs.resize(ParamVars.size(), nullptr);
// First pass over all \\param commands: resolve all parameter names.
for (Comment::child_iterator I = FC->child_begin(), E = FC->child_end();
@@ -783,11 +813,14 @@ bool Sema::isAnyFunctionDecl() {
}
bool Sema::isFunctionOrMethodVariadic() {
- if (!isAnyFunctionDecl() && !isObjCMethodDecl())
+ if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl())
return false;
if (const FunctionDecl *FD =
dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl))
return FD->isVariadic();
+ if (const FunctionTemplateDecl *FTD =
+ dyn_cast<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl))
+ return FTD->getTemplatedDecl()->isVariadic();
if (const ObjCMethodDecl *MD =
dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
return MD->isVariadic();
@@ -812,7 +845,7 @@ bool Sema::isFunctionPointerVarDecl() {
}
return false;
}
-
+
bool Sema::isObjCPropertyDecl() {
if (!ThisDeclInfo)
return false;
@@ -834,8 +867,8 @@ bool Sema::isRecordLikeDecl() {
return false;
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
- return isUnionDecl() || isClassOrStructDecl()
- || isObjCInterfaceDecl() || isObjCProtocolDecl();
+ return isUnionDecl() || isClassOrStructDecl() || isObjCInterfaceDecl() ||
+ isObjCProtocolDecl();
}
bool Sema::isUnionDecl() {
@@ -848,7 +881,7 @@ bool Sema::isUnionDecl() {
return RD->isUnion();
return false;
}
-
+
bool Sema::isClassOrStructDecl() {
if (!ThisDeclInfo)
return false;
@@ -858,7 +891,7 @@ bool Sema::isClassOrStructDecl() {
isa<RecordDecl>(ThisDeclInfo->CurrentDecl) &&
!isUnionDecl();
}
-
+
bool Sema::isClassTemplateDecl() {
if (!ThisDeclInfo)
return false;
@@ -874,7 +907,7 @@ bool Sema::isFunctionTemplateDecl() {
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
return ThisDeclInfo->CurrentDecl &&
- (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
+ (isa<FunctionTemplateDecl>(ThisDeclInfo->CurrentDecl));
}
bool Sema::isObjCInterfaceDecl() {
@@ -885,7 +918,7 @@ bool Sema::isObjCInterfaceDecl() {
return ThisDeclInfo->CurrentDecl &&
isa<ObjCInterfaceDecl>(ThisDeclInfo->CurrentDecl);
}
-
+
bool Sema::isObjCProtocolDecl() {
if (!ThisDeclInfo)
return false;
@@ -894,7 +927,7 @@ bool Sema::isObjCProtocolDecl() {
return ThisDeclInfo->CurrentDecl &&
isa<ObjCProtocolDecl>(ThisDeclInfo->CurrentDecl);
}
-
+
ArrayRef<const ParmVarDecl *> Sema::getParamVars() {
if (!ThisDeclInfo->IsFilled)
inspectThisDecl();
@@ -930,7 +963,7 @@ class SimpleTypoCorrector {
public:
SimpleTypoCorrector(StringRef Typo) :
Typo(Typo), MaxEditDistance((Typo.size() + 2) / 3),
- BestDecl(NULL), BestEditDistance(MaxEditDistance + 1),
+ BestDecl(nullptr), BestEditDistance(MaxEditDistance + 1),
BestIndex(0), NextIndex(0)
{ }
@@ -938,7 +971,7 @@ public:
const NamedDecl *getBestDecl() const {
if (BestEditDistance > MaxEditDistance)
- return NULL;
+ return nullptr;
return BestDecl;
}
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 6bd985851a39..7448de2ffbc9 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/Decl.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
@@ -29,7 +30,6 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/type_traits.h"
#include <algorithm>
using namespace clang;
@@ -158,8 +158,7 @@ static bool usesTypeVisibility(const NamedDecl *D) {
/// Does the given declaration have member specialization information,
/// and if so, is it an explicit specialization?
template <class T> static typename
-llvm::enable_if_c<!llvm::is_base_of<RedeclarableTemplateDecl, T>::value,
- bool>::type
+std::enable_if<!std::is_base_of<RedeclarableTemplateDecl, T>::value, bool>::type
isExplicitMemberSpecialization(const T *D) {
if (const MemberSpecializationInfo *member =
D->getMemberSpecializationInfo()) {
@@ -209,11 +208,8 @@ static Optional<Visibility> getVisibilityOf(const NamedDecl *D,
// If we're on Mac OS X, an 'availability' for Mac OS X attribute
// implies visibility(default).
if (D->getASTContext().getTargetInfo().getTriple().isOSDarwin()) {
- for (specific_attr_iterator<AvailabilityAttr>
- A = D->specific_attr_begin<AvailabilityAttr>(),
- AEnd = D->specific_attr_end<AvailabilityAttr>();
- A != AEnd; ++A)
- if ((*A)->getPlatform()->getName().equals("macosx"))
+ for (const auto *A : D->specific_attrs<AvailabilityAttr>())
+ if (A->getPlatform()->getName().equals("macosx"))
return DefaultVisibility;
}
@@ -231,23 +227,21 @@ getLVForType(const Type &T, LVComputationKind computation) {
/// template parameter list. For visibility purposes, template
/// parameters are part of the signature of a template.
static LinkageInfo
-getLVForTemplateParameterList(const TemplateParameterList *params,
+getLVForTemplateParameterList(const TemplateParameterList *Params,
LVComputationKind computation) {
LinkageInfo LV;
- for (TemplateParameterList::const_iterator P = params->begin(),
- PEnd = params->end();
- P != PEnd; ++P) {
-
+ for (const NamedDecl *P : *Params) {
// Template type parameters are the most common and never
// contribute to visibility, pack or not.
- if (isa<TemplateTypeParmDecl>(*P))
+ if (isa<TemplateTypeParmDecl>(P))
continue;
// Non-type template parameters can be restricted by the value type, e.g.
// template <enum X> class A { ... };
// We have to be careful here, though, because we can be dealing with
// dependent types.
- if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
+ if (const NonTypeTemplateParmDecl *NTTP =
+ dyn_cast<NonTypeTemplateParmDecl>(P)) {
// Handle the non-pack case first.
if (!NTTP->isExpandedParameterPack()) {
if (!NTTP->getType()->isDependentType()) {
@@ -267,7 +261,7 @@ getLVForTemplateParameterList(const TemplateParameterList *params,
// Template template parameters can be restricted by their
// template parameters, recursively.
- TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
+ const TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(P);
// Handle the non-pack case first.
if (!TTP->isExpandedParameterPack()) {
@@ -292,7 +286,7 @@ static LinkageInfo getLVForDecl(const NamedDecl *D,
LVComputationKind computation);
static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
- const Decl *Ret = NULL;
+ const Decl *Ret = nullptr;
const DeclContext *DC = D->getDeclContext();
while (DC->getDeclKind() != Decl::TranslationUnit) {
if (isa<FunctionDecl>(DC) || isa<BlockDecl>(DC))
@@ -307,43 +301,41 @@ static const Decl *getOutermostFuncOrBlockContext(const Decl *D) {
///
/// Note that we don't take an LVComputationKind because we always
/// want to honor the visibility of template arguments in the same way.
-static LinkageInfo
-getLVForTemplateArgumentList(ArrayRef<TemplateArgument> args,
- LVComputationKind computation) {
+static LinkageInfo getLVForTemplateArgumentList(ArrayRef<TemplateArgument> Args,
+ LVComputationKind computation) {
LinkageInfo LV;
- for (unsigned i = 0, e = args.size(); i != e; ++i) {
- const TemplateArgument &arg = args[i];
- switch (arg.getKind()) {
+ for (const TemplateArgument &Arg : Args) {
+ switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Integral:
case TemplateArgument::Expression:
continue;
case TemplateArgument::Type:
- LV.merge(getLVForType(*arg.getAsType(), computation));
+ LV.merge(getLVForType(*Arg.getAsType(), computation));
continue;
case TemplateArgument::Declaration:
- if (NamedDecl *ND = dyn_cast<NamedDecl>(arg.getAsDecl())) {
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl())) {
assert(!usesTypeVisibility(ND));
LV.merge(getLVForDecl(ND, computation));
}
continue;
case TemplateArgument::NullPtr:
- LV.merge(arg.getNullPtrType()->getLinkageAndVisibility());
+ LV.merge(Arg.getNullPtrType()->getLinkageAndVisibility());
continue;
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- if (TemplateDecl *Template
- = arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
+ if (TemplateDecl *Template =
+ Arg.getAsTemplateOrTemplatePattern().getAsTemplateDecl())
LV.merge(getLVForDecl(Template, computation));
continue;
case TemplateArgument::Pack:
- LV.merge(getLVForTemplateArgumentList(arg.getPackAsArray(), computation));
+ LV.merge(getLVForTemplateArgumentList(Arg.getPackAsArray(), computation));
continue;
}
llvm_unreachable("bad template argument kind");
@@ -479,6 +471,58 @@ static void mergeTemplateLV(LinkageInfo &LV,
LV.mergeExternalVisibility(argsLV);
}
+/// Should we consider visibility associated with the template
+/// arguments and parameters of the given variable template
+/// specialization? As usual, follow class template specialization
+/// logic up to initialization.
+static bool shouldConsiderTemplateVisibility(
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ // Include visibility from the template parameters and arguments
+ // only if this is not an explicit instantiation or specialization
+ // with direct explicit visibility (and note that implicit
+ // instantiations won't have a direct attribute).
+ if (!spec->isExplicitInstantiationOrSpecialization())
+ return true;
+
+ // An explicit variable specialization is an independent, top-level
+ // declaration. As such, if it has an explicit visibility attribute,
+ // that must directly express the user's intent, and we should honor
+ // it.
+ if (spec->isExplicitSpecialization() &&
+ hasExplicitVisibilityAlready(computation))
+ return false;
+
+ return !hasDirectVisibilityAttribute(spec, computation);
+}
+
+/// Merge in template-related linkage and visibility for the given
+/// variable template specialization. As usual, follow class template
+/// specialization logic up to initialization.
+static void mergeTemplateLV(LinkageInfo &LV,
+ const VarTemplateSpecializationDecl *spec,
+ LVComputationKind computation) {
+ bool considerVisibility = shouldConsiderTemplateVisibility(spec, computation);
+
+ // Merge information from the template parameters, but ignore
+ // visibility if we're only considering template arguments.
+
+ VarTemplateDecl *temp = spec->getSpecializedTemplate();
+ LinkageInfo tempLV =
+ getLVForTemplateParameterList(temp->getTemplateParameters(), computation);
+ LV.mergeMaybeWithVisibility(tempLV,
+ considerVisibility && !hasExplicitVisibilityAlready(computation));
+
+ // Merge information from the template arguments. We ignore
+ // template-argument visibility if we've got an explicit
+ // instantiation with a visibility attribute.
+ const TemplateArgumentList &templateArgs = spec->getTemplateArgs();
+ LinkageInfo argsLV = getLVForTemplateArgumentList(templateArgs, computation);
+ if (considerVisibility)
+ LV.mergeVisibility(argsLV);
+ LV.mergeExternalVisibility(argsLV);
+}
+
static bool useInlineVisibilityHidden(const NamedDecl *D) {
// FIXME: we should warn if -fvisibility-inlines-hidden is used with c.
const LangOptions &Opts = D->getASTContext().getLangOpts();
@@ -498,7 +542,7 @@ static bool useInlineVisibilityHidden(const NamedDecl *D) {
TSK = MSI->getTemplateSpecializationKind();
}
- const FunctionDecl *Def = 0;
+ const FunctionDecl *Def = nullptr;
// InlineVisibilityHidden only applies to definitions, and
// isInlined() only gives meaningful answers on definitions
// anyway.
@@ -512,9 +556,9 @@ template <typename T> static bool isFirstInExternCContext(T *D) {
return First->isInExternCContext();
}
-static bool isSingleLineExternC(const Decl &D) {
+static bool isSingleLineLanguageLinkage(const Decl &D) {
if (const LinkageSpecDecl *SD = dyn_cast<LinkageSpecDecl>(D.getDeclContext()))
- if (SD->getLanguage() == LinkageSpecDecl::lang_c && !SD->hasBraces())
+ if (!SD->hasBraces())
return true;
return false;
}
@@ -548,7 +592,7 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (Var->getStorageClass() != SC_Extern &&
Var->getStorageClass() != SC_PrivateExtern &&
- !isSingleLineExternC(*Var))
+ !isSingleLineLanguageLinkage(*Var))
return LinkageInfo::internal();
}
@@ -561,16 +605,10 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (PrevVar->getStorageClass() == SC_Static)
return LinkageInfo::internal();
}
- } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) {
+ } 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.
- const FunctionDecl *Function = 0;
- if (const FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(D))
- Function = FunTmpl->getTemplatedDecl();
- else
- Function = cast<FunctionDecl>(D);
// Explicitly declared static.
if (Function->getCanonicalDecl()->getStorageClass() == SC_Static)
@@ -676,6 +714,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
// C99 6.2.2p4 and propagating the visibility attribute, so we don't have
// to do it here.
+ // As per function and class template specializations (below),
+ // consider LV for the template and template arguments. We're at file
+ // scope, so we do not need to worry about nested specializations.
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ mergeTemplateLV(LV, spec, computation);
+ }
+
// - a function, unless it has internal linkage; or
} else if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
// In theory, we can modify the function's LV by the LV of its
@@ -782,11 +828,18 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// really have linkage, but it's convenient to say they do for the
// purposes of calculating linkage of pointer-to-data-member
// template arguments.
+ //
+ // Templates also don't officially have linkage, but since we ignore
+ // the C++ standard and look at template arguments when determining
+ // linkage and visibility of a template specialization, we might hit
+ // a template template argument that way. If we do, we need to
+ // consider its linkage.
if (!(isa<CXXMethodDecl>(D) ||
isa<VarDecl>(D) ||
isa<FieldDecl>(D) ||
isa<IndirectFieldDecl>(D) ||
- isa<TagDecl>(D)))
+ isa<TagDecl>(D) ||
+ isa<TemplateDecl>(D)))
return LinkageInfo::none();
LinkageInfo LV;
@@ -825,7 +878,7 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// we need to completely ignore the visibility from it.
// Specifically, if this decl exists and has an explicit attribute.
- const NamedDecl *explicitSpecSuppressor = 0;
+ const NamedDecl *explicitSpecSuppressor = nullptr;
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
// If the type of the function uses a type with unique-external
@@ -876,6 +929,10 @@ static LinkageInfo getLVForClassMember(const NamedDecl *D,
// Static data members.
} else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+ if (const VarTemplateSpecializationDecl *spec
+ = dyn_cast<VarTemplateSpecializationDecl>(VD))
+ mergeTemplateLV(LV, spec, computation);
+
// Modify the variable's linkage by its type, but ignore the
// type's visibility unless it's a definition.
LinkageInfo typeLV = getLVForType(*VD->getType(), computation);
@@ -989,6 +1046,10 @@ getExplicitVisibilityAux(const NamedDecl *ND,
return getVisibilityOf(InstantiatedFrom, kind);
}
+ if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(Var))
+ return getVisibilityOf(VTSD->getSpecializedTemplate()->getTemplatedDecl(),
+ kind);
+
return None;
}
// Also handle function template specializations.
@@ -1242,16 +1303,13 @@ public:
// We have just computed the linkage for this decl. By induction we know
// that all other computed linkages match, check that the one we just
- // computed
- // also does.
- NamedDecl *Old = NULL;
- for (NamedDecl::redecl_iterator I = D->redecls_begin(),
- E = D->redecls_end();
- I != E; ++I) {
- NamedDecl *T = cast<NamedDecl>(*I);
+ // computed also does.
+ NamedDecl *Old = nullptr;
+ for (auto I : D->redecls()) {
+ NamedDecl *T = cast<NamedDecl>(I);
if (T == D)
continue;
- if (T->hasCachedLinkage()) {
+ if (!T->isInvalidDecl() && T->hasCachedLinkage()) {
Old = T;
break;
}
@@ -1270,13 +1328,9 @@ static LinkageInfo getLVForDecl(const NamedDecl *D,
}
std::string NamedDecl::getQualifiedNameAsString() const {
- return getQualifiedNameAsString(getASTContext().getPrintingPolicy());
-}
-
-std::string NamedDecl::getQualifiedNameAsString(const PrintingPolicy &P) const {
std::string QualName;
llvm::raw_string_ostream OS(QualName);
- printQualifiedName(OS, P);
+ printQualifiedName(OS, getASTContext().getPrintingPolicy());
return OS.str();
}
@@ -1313,17 +1367,20 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
TemplateArgs.size(),
P);
} else if (const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(*I)) {
+ if (P.SuppressUnwrittenScope &&
+ (ND->isAnonymousNamespace() || ND->isInline()))
+ continue;
if (ND->isAnonymousNamespace())
- OS << "<anonymous namespace>";
+ OS << "(anonymous namespace)";
else
OS << *ND;
} else if (const RecordDecl *RD = dyn_cast<RecordDecl>(*I)) {
if (!RD->getIdentifier())
- OS << "<anonymous " << RD->getKindName() << '>';
+ OS << "(anonymous " << RD->getKindName() << ')';
else
OS << *RD;
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
- const FunctionProtoType *FT = 0;
+ const FunctionProtoType *FT = nullptr;
if (FD->hasWrittenPrototype())
FT = dyn_cast<FunctionProtoType>(FD->getType()->castAs<FunctionType>());
@@ -1352,7 +1409,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
if (getDeclName())
OS << *this;
else
- OS << "<anonymous>";
+ OS << "(anonymous)";
}
void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
@@ -1392,6 +1449,7 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
if (isa<ObjCMethodDecl>(this))
return false;
+ // FIXME: Is this correct if one of the decls comes from an inline namespace?
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
@@ -1418,14 +1476,19 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const {
// A typedef of an Objective-C class type can replace an Objective-C class
// declaration or definition, and vice versa.
+ // FIXME: Is this correct if one of the decls comes from an inline namespace?
if ((isa<TypedefNameDecl>(this) && isa<ObjCInterfaceDecl>(OldD)) ||
(isa<ObjCInterfaceDecl>(this) && isa<TypedefNameDecl>(OldD)))
return true;
-
+
// For non-function declarations, if the declarations are of the
- // same kind then this must be a redeclaration, or semantic analysis
- // would not have given us the new declaration.
- return this->getKind() == OldD->getKind();
+ // same kind and have the same parent then this must be a redeclaration,
+ // or semantic analysis would not have given us the new declaration.
+ // Note that inline namespaces can give us two declarations with the same
+ // name and kind in the same scope but different contexts.
+ return this->getKind() == OldD->getKind() &&
+ this->getDeclContext()->getRedeclContext()->Equals(
+ OldD->getDeclContext()->getRedeclContext());
}
bool NamedDecl::hasLinkage() const {
@@ -1453,11 +1516,9 @@ bool NamedDecl::isCXXInstanceMember() const {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<MSPropertyDecl>(D))
return true;
- if (isa<CXXMethodDecl>(D))
- return cast<CXXMethodDecl>(D)->isInstance();
- if (isa<FunctionTemplateDecl>(D))
- return cast<CXXMethodDecl>(cast<FunctionTemplateDecl>(D)
- ->getTemplatedDecl())->isInstance();
+ if (const CXXMethodDecl *MD =
+ dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()))
+ return MD->isInstance();
return false;
}
@@ -1574,7 +1635,9 @@ bool typeIsPostfix(clang::QualType QT) {
SourceRange DeclaratorDecl::getSourceRange() const {
SourceLocation RangeEnd = getLocation();
if (TypeSourceInfo *TInfo = getTypeSourceInfo()) {
- if (typeIsPostfix(TInfo->getType()))
+ // If the declaration has no name or the type extends past the name take the
+ // end location of the type.
+ if (!getDeclName() || typeIsPostfix(TInfo->getType()))
RangeEnd = TInfo->getTypeLoc().getSourceRange().getEnd();
}
return SourceRange(getOuterLocStart(), RangeEnd);
@@ -1584,13 +1647,13 @@ void
QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
unsigned NumTPLists,
TemplateParameterList **TPLists) {
- assert((NumTPLists == 0 || TPLists != 0) &&
+ assert((NumTPLists == 0 || TPLists != nullptr) &&
"Empty array of template parameters with positive size!");
// Free previous template parameters (if any).
if (NumTemplParamLists > 0) {
Context.Deallocate(TemplParamLists);
- TemplParamLists = 0;
+ TemplParamLists = nullptr;
NumTemplParamLists = 0;
}
// Set info on matched template parameter lists (if any).
@@ -1620,12 +1683,16 @@ const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
llvm_unreachable("Invalid storage class");
}
-VarDecl::VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo, StorageClass SC)
- : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc), Init() {
- assert(sizeof(VarDeclBitfields) <= sizeof(unsigned));
- assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned));
+VarDecl::VarDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ StorageClass SC)
+ : DeclaratorDecl(DK, DC, IdLoc, Id, T, TInfo, StartLoc),
+ redeclarable_base(C), Init() {
+ static_assert(sizeof(VarDeclBitfields) <= sizeof(unsigned),
+ "VarDeclBitfields too large!");
+ static_assert(sizeof(ParmVarDeclBitfields) <= sizeof(unsigned),
+ "ParmVarDeclBitfields too large!");
AllBits = 0;
VarDeclBits.SClass = SC;
// Everything else is implicitly initialized to false.
@@ -1635,13 +1702,13 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartL, SourceLocation IdL,
IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
StorageClass S) {
- return new (C) VarDecl(Var, DC, StartL, IdL, Id, T, TInfo, S);
+ return new (C, DC) VarDecl(Var, C, DC, StartL, IdL, Id, T, TInfo, S);
}
VarDecl *VarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(VarDecl));
- return new (Mem) VarDecl(Var, 0, SourceLocation(), SourceLocation(), 0,
- QualType(), 0, SC_None);
+ return new (C, ID)
+ VarDecl(Var, C, nullptr, SourceLocation(), SourceLocation(), nullptr,
+ QualType(), nullptr, SC_None);
}
void VarDecl::setStorageClass(StorageClass SC) {
@@ -1649,6 +1716,21 @@ void VarDecl::setStorageClass(StorageClass SC) {
VarDeclBits.SClass = SC;
}
+VarDecl::TLSKind VarDecl::getTLSKind() const {
+ switch (VarDeclBits.TSCSpec) {
+ case TSCS_unspecified:
+ if (hasAttr<ThreadAttr>())
+ return TLS_Static;
+ return TLS_None;
+ case TSCS___thread: // Fall through.
+ case TSCS__Thread_local:
+ return TLS_Static;
+ case TSCS_thread_local:
+ return TLS_Dynamic;
+ }
+ llvm_unreachable("Unknown thread storage class specifier!");
+}
+
SourceRange VarDecl::getSourceRange() const {
if (const Expr *Init = getInit()) {
SourceLocation InitEnd = Init->getLocEnd();
@@ -1661,7 +1743,7 @@ SourceRange VarDecl::getSourceRange() const {
}
template<typename T>
-static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
+static LanguageLinkage getDeclLanguageLinkage(const T &D) {
// C++ [dcl.link]p1: All function types, function names with external linkage,
// and variable names with external linkage have a language linkage.
if (!D.hasExternalFormalLinkage())
@@ -1689,7 +1771,7 @@ static LanguageLinkage getLanguageLinkageTemplate(const T &D) {
}
template<typename T>
-static bool isExternCTemplate(const T &D) {
+static bool isDeclExternC(const T &D) {
// Since the context is ignored for class members, they can only have C++
// language linkage or no language linkage.
const DeclContext *DC = D.getDeclContext();
@@ -1702,11 +1784,11 @@ static bool isExternCTemplate(const T &D) {
}
LanguageLinkage VarDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool VarDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool VarDecl::isInExternCContext() const {
@@ -1775,7 +1857,7 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
// A declaration directly contained in a linkage-specification is treated
// as if it contains the extern specifier for the purpose of determining
// the linkage of the declared name and whether it is a definition.
- if (isSingleLineExternC(*this))
+ if (isSingleLineLanguageLinkage(*this))
return DeclarationOnly;
// C99 6.9.2p2:
@@ -1794,38 +1876,35 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition(
VarDecl *VarDecl::getActingDefinition() {
DefinitionKind Kind = isThisDeclarationADefinition();
if (Kind != TentativeDefinition)
- return 0;
+ return nullptr;
- VarDecl *LastTentative = 0;
+ VarDecl *LastTentative = nullptr;
VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- Kind = (*I)->isThisDeclarationADefinition();
+ for (auto I : First->redecls()) {
+ Kind = I->isThisDeclarationADefinition();
if (Kind == Definition)
- return 0;
+ return nullptr;
else if (Kind == TentativeDefinition)
- LastTentative = *I;
+ LastTentative = I;
}
return LastTentative;
}
VarDecl *VarDecl::getDefinition(ASTContext &C) {
VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- if ((*I)->isThisDeclarationADefinition(C) == Definition)
- return *I;
+ for (auto I : First->redecls()) {
+ if (I->isThisDeclarationADefinition(C) == Definition)
+ return I;
}
- return 0;
+ return nullptr;
}
VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
DefinitionKind Kind = DeclarationOnly;
const VarDecl *First = getFirstDecl();
- for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end();
- I != E; ++I) {
- Kind = std::max(Kind, (*I)->isThisDeclarationADefinition(C));
+ for (auto I : First->redecls()) {
+ Kind = std::max(Kind, I->isThisDeclarationADefinition(C));
if (Kind == Definition)
break;
}
@@ -1834,15 +1913,13 @@ VarDecl::DefinitionKind VarDecl::hasDefinition(ASTContext &C) const {
}
const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
- redecl_iterator I = redecls_begin(), E = redecls_end();
- while (I != E && !I->getInit())
- ++I;
-
- if (I != E) {
- D = *I;
- return I->getInit();
+ for (auto I : redecls()) {
+ if (auto Expr = I->getInit()) {
+ D = I;
+ return Expr;
+ }
}
- return 0;
+ return nullptr;
}
bool VarDecl::isOutOfLine() const {
@@ -1863,15 +1940,14 @@ bool VarDecl::isOutOfLine() const {
VarDecl *VarDecl::getOutOfLineDefinition() {
if (!isStaticDataMember())
- return 0;
-
- for (VarDecl::redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
- RD != RDEnd; ++RD) {
+ return nullptr;
+
+ for (auto RD : redecls()) {
if (RD->getLexicalDeclContext()->isFileContext())
- return *RD;
+ return RD;
}
-
- return 0;
+
+ return nullptr;
}
void VarDecl::setInit(Expr *I) {
@@ -1948,7 +2024,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() ? 0 : &Eval->Evaluated;
+ return Eval->Evaluated.isUninit() ? nullptr : &Eval->Evaluated;
const Expr *Init = cast<Expr>(Eval->Value);
assert(!Init->isValueDependent());
@@ -1957,7 +2033,7 @@ APValue *VarDecl::evaluateValue(
// FIXME: Produce a diagnostic for self-initialization.
Eval->CheckedICE = true;
Eval->IsICE = false;
- return 0;
+ return nullptr;
}
Eval->IsEvaluating = true;
@@ -1983,7 +2059,7 @@ APValue *VarDecl::evaluateValue(
Eval->IsICE = Result && Notes.empty();
}
- return Result ? &Eval->Evaluated : 0;
+ return Result ? &Eval->Evaluated : nullptr;
}
bool VarDecl::checkInitIsICE() const {
@@ -2025,8 +2101,8 @@ bool VarDecl::checkInitIsICE() const {
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
return cast<VarDecl>(MSI->getInstantiatedFrom());
-
- return 0;
+
+ return nullptr;
}
TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const {
@@ -2066,7 +2142,7 @@ MemberSpecializationInfo *VarDecl::getMemberSpecializationInfo() const {
// return getASTContext().getInstantiatedFromStaticDataMember(this);
return getASTContext().getTemplateOrSpecializationInfo(this)
.dyn_cast<MemberSpecializationInfo *>();
- return 0;
+ return nullptr;
}
void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK,
@@ -2108,8 +2184,8 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, Expr *DefArg) {
- return new (C) ParmVarDecl(ParmVar, DC, StartLoc, IdLoc, Id, T, TInfo,
- S, DefArg);
+ return new (C, DC) ParmVarDecl(ParmVar, C, DC, StartLoc, IdLoc, Id, T, TInfo,
+ S, DefArg);
}
QualType ParmVarDecl::getOriginalType() const {
@@ -2121,9 +2197,9 @@ QualType ParmVarDecl::getOriginalType() const {
}
ParmVarDecl *ParmVarDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ParmVarDecl));
- return new (Mem) ParmVarDecl(ParmVar, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, SC_None, 0);
+ return new (C, ID)
+ ParmVarDecl(ParmVar, C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, QualType(), nullptr, SC_None, nullptr);
}
SourceRange ParmVarDecl::getSourceRange() const {
@@ -2196,9 +2272,9 @@ bool FunctionDecl::isVariadic() const {
}
bool FunctionDecl::hasBody(const FunctionDecl *&Definition) const {
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ for (auto I : redecls()) {
if (I->Body || I->IsLateTemplateParsed) {
- Definition = *I;
+ Definition = I;
return true;
}
}
@@ -2221,10 +2297,10 @@ bool FunctionDecl::hasTrivialBody() const
}
bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ for (auto I : redecls()) {
if (I->IsDeleted || I->IsDefaulted || I->Body || I->IsLateTemplateParsed ||
I->hasAttr<AliasAttr>()) {
- Definition = I->IsDeleted ? I->getCanonicalDecl() : *I;
+ Definition = I->IsDeleted ? I->getCanonicalDecl() : I;
return true;
}
}
@@ -2234,12 +2310,12 @@ bool FunctionDecl::isDefined(const FunctionDecl *&Definition) const {
Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
if (!hasBody(Definition))
- return 0;
+ return nullptr;
if (Definition->Body)
return Definition->Body.get(getASTContext().getExternalSource());
- return 0;
+ return nullptr;
}
void FunctionDecl::setBody(Stmt *B) {
@@ -2303,11 +2379,12 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
getDeclName().getCXXOverloadedOperator() == OO_Array_New ||
getDeclName().getCXXOverloadedOperator() == OO_Array_Delete);
- if (isa<CXXRecordDecl>(getDeclContext())) return false;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return false;
const FunctionProtoType *proto = getType()->castAs<FunctionProtoType>();
- if (proto->getNumArgs() != 2 || proto->isVariadic()) return false;
+ if (proto->getNumParams() != 2 || proto->isVariadic())
+ return false;
ASTContext &Context =
cast<TranslationUnitDecl>(getDeclContext()->getRedeclContext())
@@ -2315,13 +2392,7 @@ bool FunctionDecl::isReservedGlobalPlacementOperator() const {
// The result type and first argument type are constant across all
// these operators. The second argument must be exactly void*.
- return (proto->getArgType(1).getCanonicalType() == Context.VoidPtrTy);
-}
-
-static bool isNamespaceStd(const DeclContext *DC) {
- const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC->getRedeclContext());
- return ND && isNamed(ND, "std") &&
- ND->getParent()->getRedeclContext()->isTranslationUnit();
+ return (proto->getParamType(1).getCanonicalType() == Context.VoidPtrTy);
}
bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
@@ -2335,20 +2406,23 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
if (isa<CXXRecordDecl>(getDeclContext()))
return false;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+
+ // This can only fail for an invalid 'operator new' declaration.
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return false;
const FunctionProtoType *FPT = getType()->castAs<FunctionProtoType>();
- if (FPT->getNumArgs() > 2 || FPT->isVariadic())
+ if (FPT->getNumParams() == 0 || FPT->getNumParams() > 2 || FPT->isVariadic())
return false;
// If this is a single-parameter function, it must be a replaceable global
// allocation or deallocation function.
- if (FPT->getNumArgs() == 1)
+ if (FPT->getNumParams() == 1)
return true;
// Otherwise, we're looking for a second parameter whose type is
// 'const std::nothrow_t &', or, in C++1y, 'std::size_t'.
- QualType Ty = FPT->getArgType(1);
+ QualType Ty = FPT->getParamType(1);
ASTContext &Ctx = getASTContext();
if (Ctx.getLangOpts().SizedDeallocation &&
Ctx.hasSameType(Ty, Ctx.getSizeType()))
@@ -2358,30 +2432,31 @@ bool FunctionDecl::isReplaceableGlobalAllocationFunction() const {
Ty = Ty->getPointeeType();
if (Ty.getCVRQualifiers() != Qualifiers::Const)
return false;
- // FIXME: Recognise nothrow_t in an inline namespace inside std?
const CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
- return RD && isNamed(RD, "nothrow_t") && isNamespaceStd(RD->getDeclContext());
+ return RD && isNamed(RD, "nothrow_t") && RD->isInStdNamespace();
}
FunctionDecl *
FunctionDecl::getCorrespondingUnsizedGlobalDeallocationFunction() const {
ASTContext &Ctx = getASTContext();
if (!Ctx.getLangOpts().SizedDeallocation)
- return 0;
+ return nullptr;
if (getDeclName().getNameKind() != DeclarationName::CXXOperatorName)
- return 0;
+ return nullptr;
if (getDeclName().getCXXOverloadedOperator() != OO_Delete &&
getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
- return 0;
+ return nullptr;
if (isa<CXXRecordDecl>(getDeclContext()))
- return 0;
- assert(getDeclContext()->getRedeclContext()->isTranslationUnit());
+ return nullptr;
+
+ if (!getDeclContext()->getRedeclContext()->isTranslationUnit())
+ return nullptr;
if (getNumParams() != 2 || isVariadic() ||
- !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getArgType(1),
+ !Ctx.hasSameType(getType()->castAs<FunctionProtoType>()->getParamType(1),
Ctx.getSizeType()))
- return 0;
+ return nullptr;
// This is a sized deallocation function. Find the corresponding unsized
// deallocation function.
@@ -2391,15 +2466,15 @@ FunctionDecl::getCorrespondingUnsizedGlobalDeallocationFunction() const {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*RI))
if (FD->getNumParams() == 1 && !FD->isVariadic())
return FD;
- return 0;
+ return nullptr;
}
LanguageLinkage FunctionDecl::getLanguageLinkage() const {
- return getLanguageLinkageTemplate(*this);
+ return getDeclLanguageLinkage(*this);
}
bool FunctionDecl::isExternC() const {
- return isExternCTemplate(*this);
+ return isDeclExternC(*this);
}
bool FunctionDecl::isInExternCContext() const {
@@ -2442,7 +2517,7 @@ FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
FunctionTemplateDecl *PrevFunTmpl
- = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+ = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : nullptr;
assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
FunTmpl->setPreviousDecl(PrevFunTmpl);
}
@@ -2488,7 +2563,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 (getAttr<OverloadableAttr>())
+ if (hasAttr<OverloadableAttr>())
return 0;
if (!Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID))
@@ -2510,16 +2585,13 @@ unsigned FunctionDecl::getBuiltinID() const {
/// based on its FunctionType. This is the length of the ParamInfo array
/// after it has been created.
unsigned FunctionDecl::getNumParams() const {
- const FunctionType *FT = getType()->castAs<FunctionType>();
- if (isa<FunctionNoProtoType>(FT))
- return 0;
- return cast<FunctionProtoType>(FT)->getNumArgs();
-
+ const FunctionProtoType *FPT = getType()->getAs<FunctionProtoType>();
+ return FPT ? FPT->getNumParams() : 0;
}
void FunctionDecl::setParams(ASTContext &C,
ArrayRef<ParmVarDecl *> NewParamInfo) {
- assert(ParamInfo == 0 && "Already has param info!");
+ assert(!ParamInfo && "Already has param info!");
assert(NewParamInfo.size() == getNumParams() && "Parameter count mismatch!");
// Zero params -> null pointer.
@@ -2536,44 +2608,67 @@ void FunctionDecl::setDeclsInPrototypeScope(ArrayRef<NamedDecl *> NewDecls) {
NamedDecl **A = new (getASTContext()) NamedDecl*[NewDecls.size()];
std::copy(NewDecls.begin(), NewDecls.end(), A);
DeclsInPrototypeScope = ArrayRef<NamedDecl *>(A, NewDecls.size());
+ // Move declarations introduced in prototype to the function context.
+ for (auto I : NewDecls) {
+ DeclContext *DC = I->getDeclContext();
+ // Forward-declared reference to an enumeration is not added to
+ // declaration scope, so skip declaration that is absent from its
+ // declaration contexts.
+ if (DC->containsDecl(I)) {
+ DC->removeDecl(I);
+ I->setDeclContext(this);
+ addDecl(I);
+ }
+ }
}
}
/// getMinRequiredArguments - Returns the minimum number of arguments
/// needed to call this function. This may be fewer than the number of
/// function parameters, if some of the parameters have default
-/// arguments (in C++) or the last parameter is a parameter pack.
+/// arguments (in C++) or are parameter packs (C++11).
unsigned FunctionDecl::getMinRequiredArguments() const {
if (!getASTContext().getLangOpts().CPlusPlus)
return getNumParams();
-
- unsigned NumRequiredArgs = getNumParams();
-
- // If the last parameter is a parameter pack, we don't need an argument for
- // it.
- if (NumRequiredArgs > 0 &&
- getParamDecl(NumRequiredArgs - 1)->isParameterPack())
- --NumRequiredArgs;
-
- // If this parameter has a default argument, we don't need an argument for
- // it.
- while (NumRequiredArgs > 0 &&
- getParamDecl(NumRequiredArgs-1)->hasDefaultArg())
- --NumRequiredArgs;
-
- // We might have parameter packs before the end. These can't be deduced,
- // but they can still handle multiple arguments.
- unsigned ArgIdx = NumRequiredArgs;
- while (ArgIdx > 0) {
- if (getParamDecl(ArgIdx - 1)->isParameterPack())
- NumRequiredArgs = ArgIdx;
-
- --ArgIdx;
- }
-
+
+ unsigned NumRequiredArgs = 0;
+ for (auto *Param : params())
+ if (!Param->isParameterPack() && !Param->hasDefaultArg())
+ ++NumRequiredArgs;
return NumRequiredArgs;
}
+/// \brief The combination of the extern and inline keywords under MSVC forces
+/// the function to be required.
+///
+/// Note: This function assumes that we will only get called when isInlined()
+/// would return true for this FunctionDecl.
+bool FunctionDecl::isMSExternInline() const {
+ assert(isInlined() && "expected to get called on an inlined function!");
+
+ const ASTContext &Context = getASTContext();
+ if (!Context.getLangOpts().MSVCCompat && !hasAttr<DLLExportAttr>())
+ return false;
+
+ for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDecl())
+ if (FD->getStorageClass() == SC_Extern)
+ return true;
+
+ return false;
+}
+
+static bool redeclForcesDefMSVC(const FunctionDecl *Redecl) {
+ if (Redecl->getStorageClass() != SC_Extern)
+ return false;
+
+ for (const FunctionDecl *FD = Redecl->getPreviousDecl(); FD;
+ FD = FD->getPreviousDecl())
+ if (FD->getStorageClass() == SC_Extern)
+ return false;
+
+ return true;
+}
+
static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
// Only consider file-scope declarations in this test.
if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
@@ -2593,7 +2688,7 @@ static bool RedeclForcesDefC99(const FunctionDecl *Redecl) {
/// \brief For a function declaration in C or C++, determine whether this
/// declaration causes the definition to be externally visible.
///
-/// Specifically, this determines if adding the current declaration to the set
+/// For instance, this determines if adding the current declaration to the set
/// of redeclarations of the given functions causes
/// isInlineDefinitionExternallyVisible to change from false to true.
bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
@@ -2602,6 +2697,13 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
ASTContext &Context = getASTContext();
+ if (Context.getLangOpts().MSVCCompat) {
+ const FunctionDecl *Definition;
+ if (hasBody(Definition) && Definition->isInlined() &&
+ redeclForcesDefMSVC(this))
+ return true;
+ }
+
if (Context.getLangOpts().GNUInline || hasAttr<GNUInlineAttr>()) {
// With GNU inlining, a declaration with 'inline' but not 'extern', forces
// an externally visible definition.
@@ -2649,6 +2751,26 @@ bool FunctionDecl::doesDeclarationForceExternallyVisibleDefinition() const {
return FoundBody;
}
+SourceRange FunctionDecl::getReturnTypeSourceRange() const {
+ const TypeSourceInfo *TSI = getTypeSourceInfo();
+ if (!TSI)
+ return SourceRange();
+ FunctionTypeLoc FTL =
+ TSI->getTypeLoc().IgnoreParens().getAs<FunctionTypeLoc>();
+ if (!FTL)
+ return SourceRange();
+
+ // Skip self-referential return types.
+ const SourceManager &SM = getASTContext().getSourceManager();
+ SourceRange RTRange = FTL.getReturnLoc().getSourceRange();
+ SourceLocation Boundary = getNameInfo().getLocStart();
+ if (RTRange.isInvalid() || Boundary.isInvalid() ||
+ !SM.isBeforeInTranslationUnit(RTRange.getEnd(), Boundary))
+ return SourceRange();
+
+ return RTRange;
+}
+
/// \brief For an inline function definition in C, or for a gnu_inline function
/// in C++, determine whether the definition will be externally visible.
///
@@ -2683,9 +2805,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
// If any declaration is 'inline' but not 'extern', then this definition
// is externally visible.
- for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
- Redecl != RedeclEnd;
- ++Redecl) {
+ for (auto Redecl : redecls()) {
if (Redecl->isInlineSpecified() &&
Redecl->getStorageClass() != SC_Extern)
return true;
@@ -2702,10 +2822,8 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
// [...] If all of the file scope declarations for a function in a
// translation unit include the inline function specifier without extern,
// then the definition in that translation unit is an inline definition.
- for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
- Redecl != RedeclEnd;
- ++Redecl) {
- if (RedeclForcesDefC99(*Redecl))
+ for (auto Redecl : redecls()) {
+ if (RedeclForcesDefC99(Redecl))
return true;
}
@@ -2731,7 +2849,7 @@ const IdentifierInfo *FunctionDecl::getLiteralIdentifier() const {
if (getDeclName().getNameKind() == DeclarationName::CXXLiteralOperatorName)
return getDeclName().getCXXLiteralIdentifier();
else
- return 0;
+ return nullptr;
}
FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
@@ -2753,8 +2871,8 @@ FunctionDecl::TemplatedKind FunctionDecl::getTemplatedKind() const {
FunctionDecl *FunctionDecl::getInstantiatedFromMemberFunction() const {
if (MemberSpecializationInfo *Info = getMemberSpecializationInfo())
return cast<FunctionDecl>(Info->getInstantiatedFrom());
-
- return 0;
+
+ return nullptr;
}
void
@@ -2784,7 +2902,7 @@ bool FunctionDecl::isImplicitlyInstantiable() const {
// It is possible to instantiate TSK_ExplicitSpecialization kind
// if the FunctionDecl has a class scope specialization pattern.
case TSK_ExplicitSpecialization:
- return getClassScopeSpecializationPattern() != 0;
+ return getClassScopeSpecializationPattern() != nullptr;
case TSK_ExplicitInstantiationDeclaration:
// Handled below.
@@ -2824,14 +2942,34 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
// Handle class scope explicit specialization special case.
if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
return getClassScopeSpecializationPattern();
-
+
+ // 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
+ // member template (which happens with nested generic lambdas).
+ // Since a lambda's call operator's body is transformed eagerly,
+ // we don't have to go hunting for a prototype definition template
+ // (i.e. instantiated-from-member-template) to use as an instantiation
+ // pattern.
+
+ if (isGenericLambdaCallOperatorSpecialization(
+ dyn_cast<CXXMethodDecl>(this))) {
+ assert(getPrimaryTemplate() && "A generic lambda specialization must be "
+ "generated from a primary call operator "
+ "template");
+ assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
+ "A generic lambda call operator template must always have a body - "
+ "even if instantiated from a prototype (i.e. as written) member "
+ "template");
+ return getPrimaryTemplate()->getTemplatedDecl();
+ }
+
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())
break;
-
Primary = Primary->getInstantiatedFromMemberTemplate();
}
@@ -2847,7 +2985,7 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->Template.getPointer();
}
- return 0;
+ return nullptr;
}
FunctionDecl *FunctionDecl::getClassScopeSpecializationPattern() const {
@@ -2861,7 +2999,7 @@ FunctionDecl::getTemplateSpecializationArgs() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArguments;
}
- return 0;
+ return nullptr;
}
const ASTTemplateArgumentListInfo *
@@ -2871,7 +3009,7 @@ FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
return Info->TemplateArgumentsAsWritten;
}
- return 0;
+ return nullptr;
}
void
@@ -3101,14 +3239,14 @@ FieldDecl *FieldDecl::Create(const ASTContext &C, DeclContext *DC,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, Expr *BW, bool Mutable,
InClassInitStyle InitStyle) {
- return new (C) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
- BW, Mutable, InitStyle);
+ return new (C, DC) FieldDecl(Decl::Field, DC, StartLoc, IdLoc, Id, T, TInfo,
+ BW, Mutable, InitStyle);
}
FieldDecl *FieldDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FieldDecl));
- return new (Mem) FieldDecl(Field, 0, SourceLocation(), SourceLocation(),
- 0, QualType(), 0, 0, false, ICIS_NoInit);
+ return new (C, ID) FieldDecl(Field, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, QualType(), nullptr,
+ nullptr, false, ICIS_NoInit);
}
bool FieldDecl::isAnonymousStructOrUnion() const {
@@ -3180,8 +3318,10 @@ TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
NamedDeclOrQualifier = TDD;
- if (TypeForDecl)
- assert(TypeForDecl->isLinkageValid());
+ if (const Type *T = getTypeForDecl()) {
+ (void)T;
+ assert(T->isLinkageValid());
+ }
assert(isLinkageValid());
}
@@ -3189,10 +3329,10 @@ void TagDecl::startDefinition() {
IsBeingDefined = true;
if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(this)) {
- struct CXXRecordDecl::DefinitionData *Data =
+ struct CXXRecordDecl::DefinitionData *Data =
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
- cast<CXXRecordDecl>(*I)->DefinitionData = Data;
+ for (auto I : redecls())
+ cast<CXXRecordDecl>(I)->DefinitionData = Data;
}
}
@@ -3224,12 +3364,11 @@ TagDecl *TagDecl::getDefinition() const {
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(this))
return CXXRD->getDefinition();
- for (redecl_iterator R = redecls_begin(), REnd = redecls_end();
- R != REnd; ++R)
+ for (auto R : redecls())
if (R->isCompleteDefinition())
- return *R;
+ return R;
- return 0;
+ return nullptr;
}
void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
@@ -3244,7 +3383,7 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
if (hasExtInfo()) {
if (getExtInfo()->NumTemplParamLists == 0) {
getASTContext().Deallocate(getExtInfo());
- NamedDeclOrQualifier = (TypedefNameDecl*) 0;
+ NamedDeclOrQualifier = (TypedefNameDecl*)nullptr;
}
else
getExtInfo()->QualifierLoc = QualifierLoc;
@@ -3275,21 +3414,28 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
EnumDecl *PrevDecl, bool IsScoped,
bool IsScopedUsingClassTag, bool IsFixed) {
- EnumDecl *Enum = new (C) EnumDecl(DC, StartLoc, IdLoc, Id, PrevDecl,
- IsScoped, IsScopedUsingClassTag, IsFixed);
+ EnumDecl *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
+ IsScoped, IsScopedUsingClassTag,
+ IsFixed);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
C.getTypeDeclType(Enum, PrevDecl);
return Enum;
}
EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumDecl));
- EnumDecl *Enum = new (Mem) EnumDecl(0, SourceLocation(), SourceLocation(),
- 0, 0, false, false, false);
+ EnumDecl *Enum =
+ new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr, false, false, false);
Enum->MayHaveOutOfDateDef = C.getLangOpts().Modules;
return Enum;
}
+SourceRange EnumDecl::getIntegerTypeRange() const {
+ if (const TypeSourceInfo *TI = getIntegerTypeSourceInfo())
+ return TI->getTypeLoc().getSourceRange();
+ return SourceRange();
+}
+
void EnumDecl::completeDefinition(QualType NewType,
QualType NewPromotionType,
unsigned NumPositiveBits,
@@ -3325,7 +3471,7 @@ EnumDecl *EnumDecl::getInstantiatedFromMemberEnum() const {
if (SpecializationInfo)
return cast<EnumDecl>(SpecializationInfo->getInstantiatedFrom());
- return 0;
+ return nullptr;
}
void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
@@ -3338,10 +3484,11 @@ void EnumDecl::setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
// RecordDecl Implementation
//===----------------------------------------------------------------------===//
-RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl *PrevDecl)
- : TagDecl(DK, TK, DC, IdLoc, Id, PrevDecl, StartLoc) {
+RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
+ DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ RecordDecl *PrevDecl)
+ : TagDecl(DK, TK, C, DC, IdLoc, Id, PrevDecl, StartLoc) {
HasFlexibleArrayMember = false;
AnonymousStructOrUnion = false;
HasObjectMember = false;
@@ -3353,8 +3500,8 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl) {
- RecordDecl* R = new (C) RecordDecl(Record, TK, DC, StartLoc, IdLoc, Id,
- PrevDecl);
+ RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
+ StartLoc, IdLoc, Id, PrevDecl);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
C.getTypeDeclType(R, PrevDecl);
@@ -3362,9 +3509,9 @@ RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
}
RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(RecordDecl));
- RecordDecl *R = new (Mem) RecordDecl(Record, TTK_Struct, 0, SourceLocation(),
- SourceLocation(), 0, 0);
+ RecordDecl *R =
+ new (C, ID) RecordDecl(Record, TTK_Struct, C, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
return R;
}
@@ -3427,7 +3574,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
if (Decls.empty())
return;
- llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
+ std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
/*FieldsAlreadyLoaded=*/false);
}
@@ -3436,7 +3583,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
//===----------------------------------------------------------------------===//
void BlockDecl::setParams(ArrayRef<ParmVarDecl *> NewParamInfo) {
- assert(ParamInfo == 0 && "Already has param info!");
+ assert(!ParamInfo && "Already has param info!");
// Zero params -> null pointer.
if (!NewParamInfo.empty()) {
@@ -3454,7 +3601,7 @@ void BlockDecl::setCaptures(ASTContext &Context,
if (begin == end) {
NumCaptures = 0;
- Captures = 0;
+ Captures = nullptr;
return;
}
@@ -3469,10 +3616,9 @@ void BlockDecl::setCaptures(ASTContext &Context,
}
bool BlockDecl::capturesVariable(const VarDecl *variable) const {
- for (capture_const_iterator
- i = capture_begin(), e = capture_end(); i != e; ++i)
+ for (const auto &I : captures())
// Only auto vars can be captured, so no redeclaration worries.
- if (i->getVariable() == variable)
+ if (I.getVariable() == variable)
return true;
return false;
@@ -3489,33 +3635,33 @@ SourceRange BlockDecl::getSourceRange() const {
void TranslationUnitDecl::anchor() { }
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
- return new (C) TranslationUnitDecl(C);
+ return new (C, (DeclContext *)nullptr) TranslationUnitDecl(C);
}
void LabelDecl::anchor() { }
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II) {
- return new (C) LabelDecl(DC, IdentL, II, 0, IdentL);
+ return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, IdentL);
}
LabelDecl *LabelDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdentL, IdentifierInfo *II,
SourceLocation GnuLabelL) {
assert(GnuLabelL != IdentL && "Use this only for GNU local labels");
- return new (C) LabelDecl(DC, IdentL, II, 0, GnuLabelL);
+ return new (C, DC) LabelDecl(DC, IdentL, II, nullptr, GnuLabelL);
}
LabelDecl *LabelDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(LabelDecl));
- return new (Mem) LabelDecl(0, SourceLocation(), 0, 0, SourceLocation());
+ return new (C, ID) LabelDecl(nullptr, SourceLocation(), nullptr, nullptr,
+ SourceLocation());
}
void ValueDecl::anchor() { }
bool ValueDecl::isWeak() const {
- for (attr_iterator I = attr_begin(), E = attr_end(); I != E; ++I)
- if (isa<WeakAttr>(*I) || isa<WeakRefAttr>(*I))
+ for (const auto *I : attrs())
+ if (isa<WeakAttr>(I) || isa<WeakRefAttr>(I))
return true;
return isWeakImported();
@@ -3527,13 +3673,13 @@ ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc,
IdentifierInfo *Id,
QualType Type) {
- return new (C) ImplicitParamDecl(DC, IdLoc, Id, Type);
+ return new (C, DC) ImplicitParamDecl(C, DC, IdLoc, Id, Type);
}
-ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
+ImplicitParamDecl *ImplicitParamDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(ImplicitParamDecl));
- return new (Mem) ImplicitParamDecl(0, SourceLocation(), 0, QualType());
+ return new (C, ID) ImplicitParamDecl(C, nullptr, SourceLocation(), nullptr,
+ QualType());
}
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
@@ -3541,66 +3687,53 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC,
- bool isInlineSpecified,
+ bool isInlineSpecified,
bool hasWrittenPrototype,
bool isConstexprSpecified) {
- FunctionDecl *New = new (C) FunctionDecl(Function, DC, StartLoc, NameInfo,
- T, TInfo, SC,
- isInlineSpecified,
- isConstexprSpecified);
+ FunctionDecl *New =
+ new (C, DC) FunctionDecl(Function, C, DC, StartLoc, NameInfo, T, TInfo,
+ SC, isInlineSpecified, isConstexprSpecified);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
}
FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FunctionDecl));
- return new (Mem) FunctionDecl(Function, 0, SourceLocation(),
- DeclarationNameInfo(), QualType(), 0,
- SC_None, false, false);
+ return new (C, ID) FunctionDecl(Function, C, nullptr, SourceLocation(),
+ DeclarationNameInfo(), QualType(), nullptr,
+ SC_None, false, false);
}
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
- return new (C) BlockDecl(DC, L);
+ return new (C, DC) BlockDecl(DC, L);
}
BlockDecl *BlockDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(BlockDecl));
- return new (Mem) BlockDecl(0, SourceLocation());
-}
-
-MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C,
- unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(MSPropertyDecl));
- return new (Mem) MSPropertyDecl(0, SourceLocation(), DeclarationName(),
- QualType(), 0, SourceLocation(),
- 0, 0);
+ return new (C, ID) BlockDecl(nullptr, SourceLocation());
}
CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC,
unsigned NumParams) {
- unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
- return new (C.Allocate(Size)) CapturedDecl(DC, NumParams);
+ return new (C, DC, NumParams * sizeof(ImplicitParamDecl *))
+ CapturedDecl(DC, NumParams);
}
CapturedDecl *CapturedDecl::CreateDeserialized(ASTContext &C, unsigned ID,
- unsigned NumParams) {
- unsigned Size = sizeof(CapturedDecl) + NumParams * sizeof(ImplicitParamDecl*);
- void *Mem = AllocateDeserializedDecl(C, ID, Size);
- return new (Mem) CapturedDecl(0, NumParams);
+ unsigned NumParams) {
+ return new (C, ID, NumParams * sizeof(ImplicitParamDecl *))
+ CapturedDecl(nullptr, NumParams);
}
EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
SourceLocation L,
IdentifierInfo *Id, QualType T,
Expr *E, const llvm::APSInt &V) {
- return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
+ return new (C, CD) EnumConstantDecl(CD, L, Id, T, E, V);
}
EnumConstantDecl *
EnumConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EnumConstantDecl));
- return new (Mem) EnumConstantDecl(0, SourceLocation(), 0, QualType(), 0,
- llvm::APSInt());
+ return new (C, ID) EnumConstantDecl(nullptr, SourceLocation(), nullptr,
+ QualType(), nullptr, llvm::APSInt());
}
void IndirectFieldDecl::anchor() { }
@@ -3609,14 +3742,14 @@ IndirectFieldDecl *
IndirectFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
IdentifierInfo *Id, QualType T, NamedDecl **CH,
unsigned CHS) {
- return new (C) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
+ return new (C, DC) IndirectFieldDecl(DC, L, Id, T, CH, CHS);
}
IndirectFieldDecl *IndirectFieldDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(IndirectFieldDecl));
- return new (Mem) IndirectFieldDecl(0, SourceLocation(), DeclarationName(),
- QualType(), 0, 0);
+ return new (C, ID) IndirectFieldDecl(nullptr, SourceLocation(),
+ DeclarationName(), QualType(), nullptr,
+ 0);
}
SourceRange EnumConstantDecl::getSourceRange() const {
@@ -3631,26 +3764,26 @@ void TypeDecl::anchor() { }
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo) {
- return new (C) TypedefDecl(DC, StartLoc, IdLoc, Id, TInfo);
+ return new (C, DC) TypedefDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
void TypedefNameDecl::anchor() { }
TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypedefDecl));
- return new (Mem) TypedefDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+ return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr);
}
TypeAliasDecl *TypeAliasDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
TypeSourceInfo *TInfo) {
- return new (C) TypeAliasDecl(DC, StartLoc, IdLoc, Id, TInfo);
+ return new (C, DC) TypeAliasDecl(C, DC, StartLoc, IdLoc, Id, TInfo);
}
TypeAliasDecl *TypeAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(TypeAliasDecl));
- return new (Mem) TypeAliasDecl(0, SourceLocation(), SourceLocation(), 0, 0);
+ return new (C, ID) TypeAliasDecl(C, nullptr, SourceLocation(),
+ SourceLocation(), nullptr, nullptr);
}
SourceRange TypedefDecl::getSourceRange() const {
@@ -3675,24 +3808,23 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
StringLiteral *Str,
SourceLocation AsmLoc,
SourceLocation RParenLoc) {
- return new (C) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
+ return new (C, DC) FileScopeAsmDecl(DC, Str, AsmLoc, RParenLoc);
}
-FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
+FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FileScopeAsmDecl));
- return new (Mem) FileScopeAsmDecl(0, 0, SourceLocation(), SourceLocation());
+ return new (C, ID) FileScopeAsmDecl(nullptr, nullptr, SourceLocation(),
+ SourceLocation());
}
void EmptyDecl::anchor() {}
EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
- return new (C) EmptyDecl(DC, L);
+ return new (C, DC) EmptyDecl(DC, L);
}
EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EmptyDecl));
- return new (Mem) EmptyDecl(0, SourceLocation());
+ return new (C, ID) EmptyDecl(nullptr, SourceLocation());
}
//===----------------------------------------------------------------------===//
@@ -3730,30 +3862,28 @@ ImportDecl::ImportDecl(DeclContext *DC, SourceLocation StartLoc,
*reinterpret_cast<SourceLocation *>(this + 1) = EndLoc;
}
-ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
+ImportDecl *ImportDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, Module *Imported,
ArrayRef<SourceLocation> IdentifierLocs) {
- void *Mem = C.Allocate(sizeof(ImportDecl) +
- IdentifierLocs.size() * sizeof(SourceLocation));
- return new (Mem) ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
+ return new (C, DC, IdentifierLocs.size() * sizeof(SourceLocation))
+ ImportDecl(DC, StartLoc, Imported, IdentifierLocs);
}
-ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
+ImportDecl *ImportDecl::CreateImplicit(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc,
- Module *Imported,
+ Module *Imported,
SourceLocation EndLoc) {
- void *Mem = C.Allocate(sizeof(ImportDecl) + sizeof(SourceLocation));
- ImportDecl *Import = new (Mem) ImportDecl(DC, StartLoc, Imported, EndLoc);
+ ImportDecl *Import =
+ new (C, DC, sizeof(SourceLocation)) ImportDecl(DC, StartLoc,
+ Imported, EndLoc);
Import->setImplicit();
return Import;
}
ImportDecl *ImportDecl::CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumLocations) {
- void *Mem = AllocateDeserializedDecl(C, ID,
- (sizeof(ImportDecl) +
- NumLocations * sizeof(SourceLocation)));
- return new (Mem) ImportDecl(EmptyShell());
+ return new (C, ID, NumLocations * sizeof(SourceLocation))
+ ImportDecl(EmptyShell());
}
ArrayRef<SourceLocation> ImportDecl::getIdentifierLocs() const {
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 121c5a671a29..2b1506d191d1 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -45,25 +45,30 @@ void Decl::updateOutOfDate(IdentifierInfo &II) const {
getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
}
-void *Decl::AllocateDeserializedDecl(const ASTContext &Context,
- unsigned ID,
- unsigned Size) {
+void *Decl::operator new(std::size_t Size, const ASTContext &Context,
+ unsigned ID, std::size_t Extra) {
// Allocate an extra 8 bytes worth of storage, which ensures that the
// resulting pointer will still be 8-byte aligned.
- void *Start = Context.Allocate(Size + 8);
+ void *Start = Context.Allocate(Size + Extra + 8);
void *Result = (char*)Start + 8;
-
+
unsigned *PrefixPtr = (unsigned *)Result - 2;
-
+
// Zero out the first 4 bytes; this is used to store the owning module ID.
PrefixPtr[0] = 0;
-
+
// Store the global declaration ID in the second 4 bytes.
PrefixPtr[1] = ID;
-
+
return Result;
}
+void *Decl::operator new(std::size_t Size, const ASTContext &Ctx,
+ DeclContext *Parent, std::size_t Extra) {
+ assert(!Parent || &Parent->getParentASTContext() == &Ctx);
+ return ::operator new(Size + Extra, Ctx);
+}
+
Module *Decl::getOwningModuleSlow() const {
assert(isFromASTFile() && "Not from AST file?");
return getASTContext().getExternalSource()->getModule(getOwningModuleID());
@@ -80,6 +85,7 @@ const char *Decl::getDeclKindName() const {
void Decl::setInvalidDecl(bool Invalid) {
InvalidDecl = Invalid;
+ assert(!isa<TagDecl>(this) || !cast<TagDecl>(this)->isCompleteDefinition());
if (Invalid && !isa<ParmVarDecl>(this)) {
// Defensive maneuver for ill-formed code: we're likely not to make it to
// a point where we set the access specifier, so default it to "public"
@@ -153,11 +159,12 @@ bool Decl::isParameterPack() const {
return isTemplateParameterPack();
}
-bool Decl::isFunctionOrFunctionTemplate() const {
- if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
- return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
-
- return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
+FunctionDecl *Decl::getAsFunction() {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this))
+ return FD;
+ if (const FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(this))
+ return FTD->getTemplatedDecl();
+ return nullptr;
}
bool Decl::isTemplateDecl() const {
@@ -171,7 +178,7 @@ const DeclContext *Decl::getParentFunctionOrMethod() const {
if (DC->isFunctionOrMethod())
return DC;
- return 0;
+ return nullptr;
}
@@ -244,6 +251,10 @@ bool Decl::isInAnonymousNamespace() const {
return false;
}
+bool Decl::isInStdNamespace() const {
+ return getDeclContext()->isStdNamespace();
+}
+
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (TranslationUnitDecl *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
@@ -306,7 +317,7 @@ bool Decl::isReferenced() const {
return true;
// Check redeclarations.
- for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I)
+ for (auto I : redecls())
if (I->Referenced)
return true;
@@ -401,8 +412,8 @@ AvailabilityResult Decl::getAvailability(std::string *Message) const {
AvailabilityResult Result = AR_Available;
std::string ResultMessage;
- for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
- if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
+ for (const auto *A : attrs()) {
+ if (const auto *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
if (Result >= AR_Deprecated)
continue;
@@ -413,13 +424,13 @@ AvailabilityResult Decl::getAvailability(std::string *Message) const {
continue;
}
- if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
+ if (const auto *Unavailable = dyn_cast<UnavailableAttr>(A)) {
if (Message)
*Message = Unavailable->getMessage();
return AR_Unavailable;
}
- if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
+ if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
AvailabilityResult AR = CheckAvailability(getASTContext(), Availability,
Message);
@@ -475,13 +486,13 @@ bool Decl::isWeakImported() const {
if (!canBeWeakImported(IsDefinition))
return false;
- for (attr_iterator A = attr_begin(), AEnd = attr_end(); A != AEnd; ++A) {
- if (isa<WeakImportAttr>(*A))
+ for (const auto *A : attrs()) {
+ if (isa<WeakImportAttr>(A))
return true;
- if (AvailabilityAttr *Availability = dyn_cast<AvailabilityAttr>(*A)) {
- if (CheckAvailability(getASTContext(), Availability, 0)
- == AR_NotYetIntroduced)
+ if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
+ if (CheckAvailability(getASTContext(), Availability,
+ nullptr) == AR_NotYetIntroduced)
return true;
}
}
@@ -662,7 +673,7 @@ SourceLocation Decl::getBodyRBrace() const {
return SourceLocation();
}
-void Decl::CheckAccessDeclContext() const {
+bool Decl::AccessDeclContextSanity() const {
#ifndef NDEBUG
// Suppress this check if any of the following hold:
// 1. this is the translation unit (and thus has no parent)
@@ -684,16 +695,35 @@ void Decl::CheckAccessDeclContext() const {
// AS_none as access specifier.
isa<CXXRecordDecl>(this) ||
isa<ClassScopeFunctionSpecializationDecl>(this))
- return;
+ return true;
assert(Access != AS_none &&
"Access specifier is AS_none inside a record decl");
#endif
+ return true;
}
static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }
+const FunctionType *Decl::getFunctionType(bool BlocksToo) const {
+ QualType Ty;
+ if (const ValueDecl *D = dyn_cast<ValueDecl>(this))
+ Ty = D->getType();
+ else if (const TypedefNameDecl *D = dyn_cast<TypedefNameDecl>(this))
+ Ty = D->getUnderlyingType();
+ else
+ return nullptr;
+
+ if (Ty->isFunctionPointerType())
+ Ty = Ty->getAs<PointerType>()->getPointeeType();
+ else if (BlocksToo && Ty->isBlockPointerType())
+ Ty = Ty->getAs<BlockPointerType>()->getPointeeType();
+
+ return Ty->getAs<FunctionType>();
+}
+
+
/// Starting at a given context (a Decl or DeclContext), look for a
/// code context that is not a closure (a lambda, block, etc.).
template <class T> static Decl *getNonClosureContext(T *D) {
@@ -712,7 +742,7 @@ template <class T> static Decl *getNonClosureContext(T *D) {
} else if (CapturedDecl *CD = dyn_cast<CapturedDecl>(D)) {
return getNonClosureContext(CD->getParent());
} else {
- return 0;
+ return nullptr;
}
}
@@ -769,6 +799,22 @@ bool DeclContext::isInlineNamespace() const {
cast<NamespaceDecl>(this)->isInline();
}
+bool DeclContext::isStdNamespace() const {
+ if (!isNamespace())
+ return false;
+
+ const NamespaceDecl *ND = cast<NamespaceDecl>(this);
+ if (ND->isInline()) {
+ return ND->getParent()->isStdNamespace();
+ }
+
+ if (!getParent()->getRedeclContext()->isTranslationUnit())
+ return false;
+
+ const IdentifierInfo *II = ND->getIdentifier();
+ return II && II->isStr("std");
+}
+
bool DeclContext::isDependentContext() const {
if (isFileContext())
return false;
@@ -811,7 +857,7 @@ static bool isLinkageSpecContext(const DeclContext *DC,
while (DC->getDeclKind() != Decl::TranslationUnit) {
if (DC->getDeclKind() == Decl::LinkageSpec)
return cast<LinkageSpecDecl>(DC)->getLanguage() == ID;
- DC = DC->getParent();
+ DC = DC->getLexicalParent();
}
return false;
}
@@ -874,18 +920,17 @@ DeclContext *DeclContext::getPrimaryContext() {
// If this is a tag type that has a definition or is currently
// being defined, that definition is our primary context.
TagDecl *Tag = cast<TagDecl>(this);
- assert(isa<TagType>(Tag->TypeForDecl) ||
- isa<InjectedClassNameType>(Tag->TypeForDecl));
if (TagDecl *Def = Tag->getDefinition())
return Def;
- if (!isa<InjectedClassNameType>(Tag->TypeForDecl)) {
- const TagType *TagTy = cast<TagType>(Tag->TypeForDecl);
- if (TagTy->isBeingDefined())
- // FIXME: is it necessarily being defined in the decl
- // that owns the type?
- return TagTy->getDecl();
+ if (const TagType *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
+ // Note, TagType::getDecl returns the (partial) definition one exists.
+ TagDecl *PossiblePartialDef = TagTy->getDecl();
+ if (PossiblePartialDef->isBeingDefined())
+ return PossiblePartialDef;
+ } else {
+ assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
}
return Tag;
@@ -918,8 +963,8 @@ std::pair<Decl *, Decl *>
DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
bool FieldsAlreadyLoaded) {
// Build up a chain of declarations via the Decl::NextInContextAndBits field.
- Decl *FirstNewDecl = 0;
- Decl *PrevDecl = 0;
+ Decl *FirstNewDecl = nullptr;
+ Decl *PrevDecl = nullptr;
for (unsigned I = 0, N = Decls.size(); I != N; ++I) {
if (FieldsAlreadyLoaded && isa<FieldDecl>(Decls[I]))
continue;
@@ -939,13 +984,12 @@ DeclContext::BuildDeclChain(ArrayRef<Decl*> Decls,
/// \brief We have just acquired external visible storage, and we already have
/// built a lookup map. For every name in the map, pull in the new names from
/// the external storage.
-void DeclContext::reconcileExternalVisibleStorage() {
+void DeclContext::reconcileExternalVisibleStorage() const {
assert(NeedToReconcileExternalVisibleStorage && LookupPtr.getPointer());
NeedToReconcileExternalVisibleStorage = false;
- StoredDeclsMap &Map = *LookupPtr.getPointer();
- for (StoredDeclsMap::iterator I = Map.begin(); I != Map.end(); ++I)
- I->second.setHasExternalDecls();
+ for (auto &Lookup : *LookupPtr.getPointer())
+ Lookup.second.setHasExternalDecls();
}
/// \brief Load the declarations within this lexical storage from an
@@ -982,8 +1026,8 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const {
// Splice the newly-read declarations into the beginning of the list
// of declarations.
Decl *ExternalFirst, *ExternalLast;
- llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls,
- FieldsAlreadyLoaded);
+ std::tie(ExternalFirst, ExternalLast) =
+ BuildDeclChain(Decls, FieldsAlreadyLoaded);
ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
FirstDecl = ExternalFirst;
if (!LastDecl)
@@ -997,6 +1041,8 @@ ExternalASTSource::SetNoExternalVisibleDeclsForName(const DeclContext *DC,
StoredDeclsMap *Map;
if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
+ if (DC->NeedToReconcileExternalVisibleStorage)
+ DC->reconcileExternalVisibleStorage();
(*Map)[Name].removeExternalDecls();
@@ -1011,6 +1057,8 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
StoredDeclsMap *Map;
if (!(Map = DC->LookupPtr.getPointer()))
Map = DC->CreateStoredDeclsMap(Context);
+ if (DC->NeedToReconcileExternalVisibleStorage)
+ DC->reconcileExternalVisibleStorage();
StoredDeclsList &List = (*Map)[Name];
@@ -1050,14 +1098,9 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
return List.getLookupResult();
}
-DeclContext::decl_iterator DeclContext::noload_decls_begin() const {
- return decl_iterator(FirstDecl);
-}
-
DeclContext::decl_iterator DeclContext::decls_begin() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage();
-
return decl_iterator(FirstDecl);
}
@@ -1082,7 +1125,7 @@ void DeclContext::removeDecl(Decl *D) {
// Remove D from the decl chain. This is O(n) but hopefully rare.
if (D == FirstDecl) {
if (D == LastDecl)
- FirstDecl = LastDecl = 0;
+ FirstDecl = LastDecl = nullptr;
else
FirstDecl = D->NextInContextAndBits.getPointer();
} else {
@@ -1097,7 +1140,7 @@ void DeclContext::removeDecl(Decl *D) {
}
// Mark that D is no longer in the decl chain.
- D->NextInContextAndBits.setPointer(0);
+ D->NextInContextAndBits.setPointer(nullptr);
// Remove D from the lookup table if necessary.
if (isa<NamedDecl>(D)) {
@@ -1187,6 +1230,10 @@ static bool shouldBeHidden(NamedDecl *D) {
/// buildLookup - Build the lookup data structure with all of the
/// declarations in this DeclContext (and any other contexts linked
/// to it or transparent contexts nested within it) and return it.
+///
+/// Note that the produced map may miss out declarations from an
+/// external source. If it does, those entries will be marked with
+/// the 'hasExternalDecls' flag.
StoredDeclsMap *DeclContext::buildLookup() {
assert(this == getPrimaryContext() && "buildLookup called on non-primary DC");
@@ -1202,7 +1249,6 @@ StoredDeclsMap *DeclContext::buildLookup() {
// We no longer have any lazy decls.
LookupPtr.setInt(false);
- NeedToReconcileExternalVisibleStorage = false;
return LookupPtr.getPointer();
}
@@ -1251,11 +1297,13 @@ DeclContext::lookup(DeclarationName Name) {
return PrimaryContext->lookup(Name);
if (hasExternalVisibleStorage()) {
+ if (NeedToReconcileExternalVisibleStorage)
+ reconcileExternalVisibleStorage();
+
StoredDeclsMap *Map = LookupPtr.getPointer();
+
if (LookupPtr.getInt())
Map = buildLookup();
- else if (NeedToReconcileExternalVisibleStorage)
- reconcileExternalVisibleStorage();
if (!Map)
Map = CreateStoredDeclsMap(getParentASTContext());
@@ -1267,7 +1315,7 @@ DeclContext::lookup(DeclarationName Name) {
return R.first->second.getLookupResult();
ExternalASTSource *Source = getParentASTContext().getExternalSource();
- if (Source->FindExternalVisibleDeclsByName(this, Name) || R.second) {
+ if (Source->FindExternalVisibleDeclsByName(this, Name) || !R.second) {
if (StoredDeclsMap *Map = LookupPtr.getPointer()) {
StoredDeclsMap::iterator I = Map->find(Name);
if (I != Map->end())
@@ -1275,7 +1323,7 @@ DeclContext::lookup(DeclarationName Name) {
}
}
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
}
StoredDeclsMap *Map = LookupPtr.getPointer();
@@ -1283,11 +1331,11 @@ DeclContext::lookup(DeclarationName Name) {
Map = buildLookup();
if (!Map)
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
StoredDeclsMap::iterator I = Map->find(Name);
if (I == Map->end())
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
return I->second.getLookupResult();
}
@@ -1324,12 +1372,12 @@ DeclContext::noload_lookup(DeclarationName Name) {
}
if (!Map)
- return lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return lookup_result(lookup_iterator(nullptr), lookup_iterator(nullptr));
StoredDeclsMap::iterator I = Map->find(Name);
- return I != Map->end()
- ? I->second.getLookupResult()
- : lookup_result(lookup_iterator(0), lookup_iterator(0));
+ return I != Map->end() ? I->second.getLookupResult()
+ : lookup_result(lookup_iterator(nullptr),
+ lookup_iterator(nullptr));
}
void DeclContext::localUncachedLookup(DeclarationName Name,
@@ -1502,13 +1550,13 @@ void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
/// Returns iterator range [First, Last) of UsingDirectiveDecls stored within
/// this context.
-DeclContext::udir_iterator_range
-DeclContext::getUsingDirectives() const {
+DeclContext::udir_range DeclContext::using_directives() const {
// FIXME: Use something more efficient than normal lookup for using
// directives. In C++, using directives are looked up more than anything else.
lookup_const_result Result = lookup(UsingDirectiveDecl::getName());
- return udir_iterator_range(reinterpret_cast<udir_iterator>(Result.begin()),
- reinterpret_cast<udir_iterator>(Result.end()));
+ return udir_range(
+ reinterpret_cast<UsingDirectiveDecl *const *>(Result.begin()),
+ reinterpret_cast<UsingDirectiveDecl *const *>(Result.end()));
}
//===----------------------------------------------------------------------===//
@@ -1568,7 +1616,7 @@ DependentDiagnostic *DependentDiagnostic::Create(ASTContext &C,
// Allocate the copy of the PartialDiagnostic via the ASTContext's
// BumpPtrAllocator, rather than the ASTContext itself.
- PartialDiagnostic::Storage *DiagStorage = 0;
+ PartialDiagnostic::Storage *DiagStorage = nullptr;
if (PDiag.hasStorage())
DiagStorage = new (C) PartialDiagnostic::Storage;
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index a17abdd0ae2a..ed26c5262a7b 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -31,8 +31,7 @@ using namespace clang;
void AccessSpecDecl::anchor() { }
AccessSpecDecl *AccessSpecDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(AccessSpecDecl));
- return new (Mem) AccessSpecDecl(EmptyShell());
+ return new (C, ID) AccessSpecDecl(EmptyShell());
}
void LazyASTUnresolvedSet::getFromExternalSource(ASTContext &C) const {
@@ -51,7 +50,7 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
Aggregate(true), PlainOldData(true), Empty(true), Polymorphic(false),
Abstract(false), IsStandardLayout(true), HasNoNonEmptyBases(true),
HasPrivateFields(false), HasProtectedFields(false), HasPublicFields(false),
- HasMutableFields(false), HasOnlyCMembers(true),
+ HasMutableFields(false), HasVariantMembers(false), HasOnlyCMembers(true),
HasInClassInitializer(false), HasUninitializedReferenceMember(false),
NeedOverloadResolutionForMoveConstructor(false),
NeedOverloadResolutionForMoveAssignment(false),
@@ -71,7 +70,8 @@ CXXRecordDecl::DefinitionData::DefinitionData(CXXRecordDecl *D)
ImplicitCopyAssignmentHasConstParam(true),
HasDeclaredCopyConstructorWithConstParam(false),
HasDeclaredCopyAssignmentWithConstParam(false),
- IsLambda(false), NumBases(0), NumVBases(0), Bases(), VBases(),
+ IsLambda(false), IsParsingBaseSpecifiers(false), NumBases(0), NumVBases(0),
+ Bases(), VBases(),
Definition(D), FirstFriend() {
}
@@ -83,20 +83,22 @@ CXXBaseSpecifier *CXXRecordDecl::DefinitionData::getVBasesSlowCase() const {
return VBases.get(Definition->getASTContext().getExternalSource());
}
-CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl *PrevDecl)
- : RecordDecl(K, TK, DC, StartLoc, IdLoc, Id, PrevDecl),
- DefinitionData(PrevDecl ? PrevDecl->DefinitionData : 0),
- TemplateOrInstantiation() { }
+CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
+ DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl)
+ : RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
+ DefinitionData(PrevDecl ? PrevDecl->DefinitionData
+ : DefinitionDataPtr(this)),
+ TemplateOrInstantiation() {}
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
CXXRecordDecl* PrevDecl,
bool DelayTypeCreation) {
- CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TK, DC, StartLoc, IdLoc,
- Id, PrevDecl);
+ CXXRecordDecl *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc,
+ IdLoc, Id, PrevDecl);
R->MayHaveOutOfDateDef = C.getLangOpts().Modules;
// FIXME: DelayTypeCreation seems like such a hack
@@ -105,29 +107,29 @@ CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
return R;
}
-CXXRecordDecl *CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
- TypeSourceInfo *Info, SourceLocation Loc,
- bool Dependent, bool IsGeneric,
- LambdaCaptureDefault CaptureDefault) {
- CXXRecordDecl* R = new (C) CXXRecordDecl(CXXRecord, TTK_Class, DC, Loc, Loc,
- 0, 0);
+CXXRecordDecl *
+CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
+ TypeSourceInfo *Info, SourceLocation Loc,
+ bool Dependent, bool IsGeneric,
+ LambdaCaptureDefault CaptureDefault) {
+ CXXRecordDecl *R =
+ new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
+ nullptr, nullptr);
R->IsBeingDefined = true;
- R->DefinitionData = new (C) struct LambdaDefinitionData(R, Info,
- Dependent,
- IsGeneric,
- CaptureDefault);
+ R->DefinitionData =
+ new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
+ CaptureDefault);
R->MayHaveOutOfDateDef = false;
R->setImplicit(true);
- C.getTypeDeclType(R, /*PrevDecl=*/0);
+ C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
return R;
}
CXXRecordDecl *
CXXRecordDecl::CreateDeserialized(const ASTContext &C, unsigned ID) {
- void *Mem = AllocateDeserializedDecl(C, ID, sizeof(CXXRecordDecl));
- CXXRecordDecl *R = new (Mem) CXXRecordDecl(CXXRecord, TTK_Struct, 0,
- SourceLocation(), SourceLocation(),
- 0, 0);
+ CXXRecordDecl *R = new (C, ID) CXXRecordDecl(
+ CXXRecord, TTK_Struct, C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr);
R->MayHaveOutOfDateDef = false;
return R;
}
@@ -205,19 +207,17 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
data().HasNonLiteralTypeFieldsOrBases = true;
// Now go through all virtual bases of this base and add them.
- for (CXXRecordDecl::base_class_iterator VBase =
- BaseClassDecl->vbases_begin(),
- E = BaseClassDecl->vbases_end(); VBase != E; ++VBase) {
+ for (const auto &VBase : BaseClassDecl->vbases()) {
// Add this base if it's not already in the list.
- if (SeenVBaseTypes.insert(C.getCanonicalType(VBase->getType()))) {
- VBases.push_back(VBase);
+ if (SeenVBaseTypes.insert(C.getCanonicalType(VBase.getType()))) {
+ VBases.push_back(&VBase);
// C++11 [class.copy]p8:
// The implicitly-declared copy constructor for a class X will have
// the form 'X::X(const X&)' if each [...] virtual base class B of X
// has a copy constructor whose first parameter is of type
// 'const B&' or 'const volatile B&' [...]
- if (CXXRecordDecl *VBaseDecl = VBase->getType()->getAsCXXRecordDecl())
+ if (CXXRecordDecl *VBaseDecl = VBase.getType()->getAsCXXRecordDecl())
if (!VBaseDecl->hasCopyConstructorWithConstParam())
data().ImplicitCopyConstructorHasConstParam = false;
}
@@ -335,8 +335,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
addedClassSubobject(BaseClassDecl);
}
- if (VBases.empty())
+ if (VBases.empty()) {
+ data().IsParsingBaseSpecifiers = false;
return;
+ }
// Create base specifier for any direct or indirect virtual bases.
data().VBases = new (C) CXXBaseSpecifier[VBases.size()];
@@ -347,6 +349,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
addedClassSubobject(Type->getAsCXXRecordDecl());
data().getVBases()[I] = *VBases[I];
}
+
+ data().IsParsingBaseSpecifiers = false;
}
void CXXRecordDecl::addedClassSubobject(CXXRecordDecl *Subobj) {
@@ -391,7 +395,7 @@ bool CXXRecordDecl::hasAnyDependentBases() const {
if (!isDependentContext())
return false;
- return !forallBases(SawBase, 0);
+ return !forallBases(SawBase, nullptr);
}
bool CXXRecordDecl::isTriviallyCopyable() const {
@@ -532,8 +536,11 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(D)) {
SMKind |= SMF_Destructor;
- if (!DD->isImplicit())
+ if (DD->isUserProvided())
data().HasIrrelevantDestructor = false;
+ // If the destructor is explicitly defaulted and not trivial or not public
+ // or if the destructor is deleted, we clear HasIrrelevantDestructor in
+ // finishedDefaultedOrDeletedMember.
// C++11 [class.dtor]p5:
// A destructor is trivial if [...] the destructor is not virtual.
@@ -656,7 +663,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
// Keep track of the presence of mutable fields.
if (Field->isMutable())
data().HasMutableFields = true;
-
+
+ // C++11 [class.union]p8, DR1460:
+ // If X is a union, a non-static data member of X that is not an anonymous
+ // union is a variant member of X.
+ if (isUnion() && !Field->isAnonymousStructOrUnion())
+ data().HasVariantMembers = true;
+
// C++0x [class]p9:
// A POD struct is a class that is both a trivial class and a
// standard-layout class, and has no non-static data members of type
@@ -692,7 +705,9 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (!T->isLiteralType(Context) || T.isVolatileQualified())
data().HasNonLiteralTypeFieldsOrBases = true;
- if (Field->hasInClassInitializer()) {
+ if (Field->hasInClassInitializer() ||
+ (Field->isAnonymousStructOrUnion() &&
+ Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
data().HasInClassInitializer = true;
// C++11 [class]p5:
@@ -809,15 +824,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
// Virtual bases and virtual methods make a class non-empty, but they
// also make it non-standard-layout so we needn't check here.
// A non-empty base class may leave the class standard-layout, but not
- // if we have arrived here, and have at least on non-static data
+ // if we have arrived here, and have at least one non-static data
// member. If IsStandardLayout remains true, then the first non-static
// data member must come through here with Empty still true, and Empty
// will subsequently be set to false below.
if (data().IsStandardLayout && data().Empty) {
- for (CXXRecordDecl::base_class_const_iterator BI = bases_begin(),
- BE = bases_end();
- BI != BE; ++BI) {
- if (Context.hasSameUnqualifiedType(BI->getType(), T)) {
+ for (const auto &BI : bases()) {
+ if (Context.hasSameUnqualifiedType(BI.getType(), T)) {
data().IsStandardLayout = false;
break;
}
@@ -862,6 +875,13 @@ void CXXRecordDecl::addedMember(Decl *D) {
if (FieldRec->hasUninitializedReferenceMember() &&
!Field->hasInClassInitializer())
data().HasUninitializedReferenceMember = true;
+
+ // C++11 [class.union]p8, DR1460:
+ // a non-static data member of an anonymous union that is a member of
+ // X is also a variant member of X.
+ if (FieldRec->hasVariantMembers() &&
+ Field->isAnonymousStructOrUnion())
+ data().HasVariantMembers = true;
}
} else {
// Base element type of field is a non-class type.
@@ -928,9 +948,11 @@ void CXXRecordDecl::finishedDefaultedOrDeletedMember(CXXMethodDecl *D) {
else if (Cons