aboutsummaryrefslogtreecommitdiffstats
path: root/include/clang
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 /include/clang
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 'include/clang')
-rw-r--r--include/clang/ARCMigrate/ARCMT.h2
-rw-r--r--include/clang/ARCMigrate/ARCMTActions.h19
-rw-r--r--include/clang/ARCMigrate/FileRemapper.h6
-rw-r--r--include/clang/AST/APValue.h123
-rw-r--r--include/clang/AST/ASTConsumer.h14
-rw-r--r--include/clang/AST/ASTContext.h227
-rw-r--r--include/clang/AST/ASTDiagnostic.h9
-rw-r--r--include/clang/AST/ASTImporter.h2
-rw-r--r--include/clang/AST/ASTLambda.h4
-rw-r--r--include/clang/AST/ASTMutationListener.h7
-rw-r--r--include/clang/AST/ASTTypeTraits.h42
-rw-r--r--include/clang/AST/ASTUnresolvedSet.h3
-rw-r--r--include/clang/AST/ASTVector.h49
-rw-r--r--include/clang/AST/Attr.h48
-rw-r--r--include/clang/AST/AttrIterator.h8
-rw-r--r--include/clang/AST/CMakeLists.txt5
-rw-r--r--include/clang/AST/CXXInheritance.h11
-rw-r--r--include/clang/AST/CanonicalType.h31
-rw-r--r--include/clang/AST/CharUnits.h9
-rw-r--r--include/clang/AST/Comment.h67
-rw-r--r--include/clang/AST/CommentCommands.td2
-rw-r--r--include/clang/AST/CommentHTMLTags.td13
-rw-r--r--include/clang/AST/CommentLexer.h16
-rw-r--r--include/clang/AST/CommentSema.h4
-rw-r--r--include/clang/AST/DataRecursiveASTVisitor.h2519
-rw-r--r--include/clang/AST/Decl.h474
-rw-r--r--include/clang/AST/DeclBase.h200
-rw-r--r--include/clang/AST/DeclCXX.h383
-rw-r--r--include/clang/AST/DeclContextInternals.h19
-rw-r--r--include/clang/AST/DeclFriend.h15
-rw-r--r--include/clang/AST/DeclGroup.h12
-rw-r--r--include/clang/AST/DeclLookups.h34
-rw-r--r--include/clang/AST/DeclObjC.h504
-rw-r--r--include/clang/AST/DeclOpenMP.h19
-rw-r--r--include/clang/AST/DeclTemplate.h288
-rw-r--r--include/clang/AST/DeclarationName.h9
-rw-r--r--include/clang/AST/DependentDiagnostic.h12
-rw-r--r--include/clang/AST/Expr.h186
-rw-r--r--include/clang/AST/ExprCXX.h392
-rw-r--r--include/clang/AST/ExprObjC.h20
-rw-r--r--include/clang/AST/ExternalASTSource.h161
-rw-r--r--include/clang/AST/LambdaCapture.h123
-rw-r--r--include/clang/AST/Makefile8
-rw-r--r--include/clang/AST/Mangle.h58
-rw-r--r--include/clang/AST/MangleNumberingContext.h10
-rw-r--r--include/clang/AST/NestedNameSpecifier.h14
-rw-r--r--include/clang/AST/OpenMPClause.h1455
-rw-r--r--include/clang/AST/OperationKinds.h5
-rw-r--r--include/clang/AST/ParentMap.h2
-rw-r--r--include/clang/AST/PrettyPrinter.h12
-rw-r--r--include/clang/AST/RawCommentList.h4
-rw-r--r--include/clang/AST/RecordLayout.h44
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2320
-rw-r--r--include/clang/AST/Redeclarable.h121
-rw-r--r--include/clang/AST/Stmt.h146
-rw-r--r--include/clang/AST/StmtCXX.h2
-rw-r--r--include/clang/AST/StmtIterator.h6
-rw-r--r--include/clang/AST/StmtObjC.h6
-rw-r--r--include/clang/AST/StmtOpenMP.h1159
-rw-r--r--include/clang/AST/TemplateBase.h36
-rw-r--r--include/clang/AST/TemplateName.h18
-rw-r--r--include/clang/AST/Type.h256
-rw-r--r--include/clang/AST/TypeLoc.h49
-rw-r--r--include/clang/AST/TypeNodes.def3
-rw-r--r--include/clang/AST/UnresolvedSet.h2
-rw-r--r--include/clang/AST/VTableBuilder.h177
-rw-r--r--include/clang/ASTMatchers/ASTMatchFinder.h4
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h316
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h470
-rw-r--r--include/clang/ASTMatchers/ASTMatchersMacros.h87
-rw-r--r--include/clang/ASTMatchers/Dynamic/Diagnostics.h8
-rw-r--r--include/clang/ASTMatchers/Dynamic/Parser.h70
-rw-r--r--include/clang/ASTMatchers/Dynamic/Registry.h67
-rw-r--r--include/clang/ASTMatchers/Dynamic/VariantValue.h49
-rw-r--r--include/clang/Analysis/Analyses/Consumed.h13
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h19
-rw-r--r--include/clang/Analysis/Analyses/FormatString.h23
-rw-r--r--include/clang/Analysis/Analyses/LiveVariables.h2
-rw-r--r--include/clang/Analysis/Analyses/PostOrderCFGView.h10
-rw-r--r--include/clang/Analysis/Analyses/ReachableCode.h17
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafety.h52
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyCommon.h393
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyLogical.h108
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyOps.def54
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTIL.h1813
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyTraverse.h936
-rw-r--r--include/clang/Analysis/Analyses/ThreadSafetyUtil.h316
-rw-r--r--include/clang/Analysis/AnalysisContext.h28
-rw-r--r--include/clang/Analysis/CFG.h167
-rw-r--r--include/clang/Analysis/FlowSensitive/DataflowSolver.h342
-rw-r--r--include/clang/Analysis/ProgramPoint.h77
-rw-r--r--include/clang/Analysis/Support/BumpVector.h8
-rw-r--r--include/clang/Basic/ABI.h8
-rw-r--r--include/clang/Basic/Attr.td1211
-rw-r--r--include/clang/Basic/AttrDocs.td1105
-rw-r--r--include/clang/Basic/AttrKinds.h1
-rw-r--r--include/clang/Basic/Attributes.h41
-rw-r--r--include/clang/Basic/Builtins.def54
-rw-r--r--include/clang/Basic/Builtins.h24
-rw-r--r--include/clang/Basic/BuiltinsAArch64.def40
-rw-r--r--include/clang/Basic/BuiltinsARM.def35
-rw-r--r--include/clang/Basic/BuiltinsMips.def18
-rw-r--r--include/clang/Basic/BuiltinsNEON.def21
-rw-r--r--include/clang/Basic/BuiltinsR600.def32
-rw-r--r--include/clang/Basic/BuiltinsX86.def7
-rw-r--r--include/clang/Basic/CMakeLists.txt7
-rw-r--r--include/clang/Basic/Diagnostic.h287
-rw-r--r--include/clang/Basic/Diagnostic.td55
-rw-r--r--include/clang/Basic/DiagnosticASTKinds.td4
-rw-r--r--include/clang/Basic/DiagnosticCategories.td1
-rw-r--r--include/clang/Basic/DiagnosticCommentKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td23
-rw-r--r--include/clang/Basic/DiagnosticDriverKinds.td29
-rw-r--r--include/clang/Basic/DiagnosticFrontendKinds.td52
-rw-r--r--include/clang/Basic/DiagnosticGroups.td141
-rw-r--r--include/clang/Basic/DiagnosticIDs.h86
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td50
-rw-r--r--include/clang/Basic/DiagnosticOptions.h6
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td214
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td1023
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td29
-rw-r--r--include/clang/Basic/FileManager.h82
-rw-r--r--include/clang/Basic/FileSystemStatCache.h48
-rw-r--r--include/clang/Basic/IdentifierTable.h13
-rw-r--r--include/clang/Basic/LLVM.h6
-rw-r--r--include/clang/Basic/LangOptions.def19
-rw-r--r--include/clang/Basic/LangOptions.h12
-rw-r--r--include/clang/Basic/Linkage.h9
-rw-r--r--include/clang/Basic/Makefile10
-rw-r--r--include/clang/Basic/Module.h88
-rw-r--r--include/clang/Basic/ObjCRuntime.h5
-rw-r--r--include/clang/Basic/OnDiskHashTable.h485
-rw-r--r--include/clang/Basic/OpenCL.h29
-rw-r--r--include/clang/Basic/OpenMPKinds.def160
-rw-r--r--include/clang/Basic/OpenMPKinds.h64
-rw-r--r--include/clang/Basic/OperatorKinds.h2
-rw-r--r--include/clang/Basic/PartialDiagnostic.h48
-rw-r--r--include/clang/Basic/PlistSupport.h122
-rw-r--r--include/clang/Basic/PrettyStackTrace.h2
-rw-r--r--include/clang/Basic/Sanitizers.def10
-rw-r--r--include/clang/Basic/SourceLocation.h30
-rw-r--r--include/clang/Basic/SourceManager.h184
-rw-r--r--include/clang/Basic/Specifiers.h10
-rw-r--r--include/clang/Basic/StmtNodes.td17
-rw-r--r--include/clang/Basic/TargetBuiltins.h42
-rw-r--r--include/clang/Basic/TargetCXXABI.h22
-rw-r--r--include/clang/Basic/TargetInfo.h84
-rw-r--r--include/clang/Basic/TargetOptions.h8
-rw-r--r--include/clang/Basic/TemplateKinds.h1
-rw-r--r--include/clang/Basic/TokenKinds.def191
-rw-r--r--include/clang/Basic/TokenKinds.h12
-rw-r--r--include/clang/Basic/TypeTraits.h26
-rw-r--r--include/clang/Basic/Version.h3
-rw-r--r--include/clang/Basic/VersionTuple.h10
-rw-r--r--include/clang/Basic/VirtualFileSystem.h283
-rw-r--r--include/clang/Basic/arm_neon.td954
-rw-r--r--include/clang/CMakeLists.txt1
-rw-r--r--include/clang/CodeGen/BackendUtil.h8
-rw-r--r--include/clang/CodeGen/CGFunctionInfo.h237
-rw-r--r--include/clang/CodeGen/CodeGenABITypes.h19
-rw-r--r--include/clang/CodeGen/CodeGenAction.h28
-rw-r--r--include/clang/CodeGen/ModuleBuilder.h2
-rw-r--r--include/clang/Config/config.h.cmake15
-rw-r--r--include/clang/Config/config.h.in14
-rw-r--r--include/clang/Driver/Action.h49
-rw-r--r--include/clang/Driver/CC1AsOptions.h37
-rw-r--r--include/clang/Driver/CC1AsOptions.td95
-rw-r--r--include/clang/Driver/CC1Options.h0
-rw-r--r--include/clang/Driver/CC1Options.td115
-rw-r--r--include/clang/Driver/CLCompatOptions.td61
-rw-r--r--include/clang/Driver/CMakeLists.txt4
-rw-r--r--include/clang/Driver/Compilation.h6
-rw-r--r--include/clang/Driver/Driver.h7
-rw-r--r--include/clang/Driver/Job.h22
-rw-r--r--include/clang/Driver/Makefile6
-rw-r--r--include/clang/Driver/Multilib.h167
-rw-r--r--include/clang/Driver/Options.h3
-rw-r--r--include/clang/Driver/Options.td391
-rw-r--r--include/clang/Driver/SanitizerArgs.h13
-rw-r--r--include/clang/Driver/ToolChain.h30
-rw-r--r--include/clang/Driver/Types.def22
-rw-r--r--include/clang/Edit/Commit.h13
-rw-r--r--include/clang/Edit/EditedSource.h11
-rw-r--r--include/clang/Edit/FileOffset.h12
-rw-r--r--include/clang/Format/Format.h208
-rw-r--r--include/clang/Frontend/ASTUnit.h201
-rw-r--r--include/clang/Frontend/ChainedDiagnosticConsumer.h20
-rw-r--r--include/clang/Frontend/ChainedIncludesSource.h75
-rw-r--r--include/clang/Frontend/CodeGenOptions.def12
-rw-r--r--include/clang/Frontend/CodeGenOptions.h53
-rw-r--r--include/clang/Frontend/CompilerInstance.h157
-rw-r--r--include/clang/Frontend/CompilerInvocation.h28
-rw-r--r--include/clang/Frontend/DependencyOutputOptions.h7
-rw-r--r--include/clang/Frontend/DiagnosticRenderer.h28
-rw-r--r--include/clang/Frontend/FrontendAction.h54
-rw-r--r--include/clang/Frontend/FrontendActions.h149
-rw-r--r--include/clang/Frontend/FrontendOptions.h14
-rw-r--r--include/clang/Frontend/FrontendPluginRegistry.h3
-rw-r--r--include/clang/Frontend/LangStandard.h16
-rw-r--r--include/clang/Frontend/LangStandards.def20
-rw-r--r--include/clang/Frontend/LayoutOverrideSource.h5
-rw-r--r--include/clang/Frontend/LogDiagnosticPrinter.h13
-rw-r--r--include/clang/Frontend/MultiplexConsumer.h43
-rw-r--r--include/clang/Frontend/SerializedDiagnosticPrinter.h13
-rw-r--r--include/clang/Frontend/TextDiagnostic.h64
-rw-r--r--include/clang/Frontend/TextDiagnosticBuffer.h9
-rw-r--r--include/clang/Frontend/TextDiagnosticPrinter.h11
-rw-r--r--include/clang/Frontend/Utils.h108
-rw-r--r--include/clang/Frontend/VerifyDiagnosticConsumer.h62
-rw-r--r--include/clang/Index/CommentToXML.h6
-rw-r--r--include/clang/Index/USRGeneration.h12
-rw-r--r--include/clang/Lex/CMakeLists.txt5
-rw-r--r--include/clang/Lex/DirectoryLookup.h20
-rw-r--r--include/clang/Lex/HeaderMap.h5
-rw-r--r--include/clang/Lex/HeaderSearch.h98
-rw-r--r--include/clang/Lex/HeaderSearchOptions.h29
-rw-r--r--include/clang/Lex/Lexer.h47
-rw-r--r--include/clang/Lex/LiteralSupport.h20
-rw-r--r--include/clang/Lex/MacroArgs.h5
-rw-r--r--include/clang/Lex/MacroInfo.h72
-rw-r--r--include/clang/Lex/Makefile13
-rw-r--r--include/clang/Lex/ModuleLoader.h36
-rw-r--r--include/clang/Lex/ModuleMap.h66
-rw-r--r--include/clang/Lex/MultipleIncludeOpt.h10
-rw-r--r--include/clang/Lex/PPCallbacks.h122
-rw-r--r--include/clang/Lex/PPConditionalDirectiveRecord.h20
-rw-r--r--include/clang/Lex/PTHLexer.h4
-rw-r--r--include/clang/Lex/PTHManager.h2
-rw-r--r--include/clang/Lex/Pragma.h12
-rw-r--r--include/clang/Lex/PreprocessingRecord.h47
-rw-r--r--include/clang/Lex/Preprocessor.h662
-rw-r--r--include/clang/Lex/PreprocessorLexer.h2
-rw-r--r--include/clang/Lex/PreprocessorOptions.h56
-rw-r--r--include/clang/Lex/Token.h28
-rw-r--r--include/clang/Lex/TokenLexer.h19
-rw-r--r--include/clang/Makefile2
-rw-r--r--include/clang/Parse/CMakeLists.txt14
-rw-r--r--include/clang/Parse/Makefile20
-rw-r--r--include/clang/Parse/ParseAST.h2
-rw-r--r--include/clang/Parse/Parser.h532
-rw-r--r--include/clang/Rewrite/Core/HTMLRewrite.h2
-rw-r--r--include/clang/Rewrite/Core/RewriteRope.h16
-rw-r--r--include/clang/Rewrite/Core/Rewriter.h4
-rw-r--r--include/clang/Rewrite/Core/TokenRewriter.h4
-rw-r--r--include/clang/Rewrite/Frontend/FixItRewriter.h10
-rw-r--r--include/clang/Rewrite/Frontend/FrontendActions.h32
-rw-r--r--include/clang/Sema/AttributeList.h220
-rw-r--r--include/clang/Sema/CodeCompleteConsumer.h48
-rw-r--r--include/clang/Sema/DeclSpec.h194
-rw-r--r--include/clang/Sema/DelayedDiagnostic.h30
-rw-r--r--include/clang/Sema/IdentifierResolver.h13
-rw-r--r--include/clang/Sema/Initialization.h73
-rw-r--r--include/clang/Sema/Lookup.h36
-rw-r--r--include/clang/Sema/LoopHint.h40
-rw-r--r--include/clang/Sema/MultiplexExternalSemaSource.h125
-rw-r--r--include/clang/Sema/ObjCMethodList.h2
-rw-r--r--include/clang/Sema/Overload.h40
-rw-r--r--include/clang/Sema/Ownership.h26
-rw-r--r--include/clang/Sema/ParsedTemplate.h4
-rw-r--r--include/clang/Sema/PrettyDeclStackTrace.h2
-rw-r--r--include/clang/Sema/Scope.h168
-rw-r--r--include/clang/Sema/ScopeInfo.h59
-rw-r--r--include/clang/Sema/Sema.h1062
-rw-r--r--include/clang/Sema/SemaInternal.h98
-rw-r--r--include/clang/Sema/SemaLambda.h75
-rw-r--r--include/clang/Sema/Template.h26
-rw-r--r--include/clang/Sema/TemplateDeduction.h11
-rw-r--r--include/clang/Sema/TypoCorrection.h32
-rw-r--r--include/clang/Sema/Weak.h2
-rw-r--r--include/clang/Serialization/ASTBitCodes.h48
-rw-r--r--include/clang/Serialization/ASTDeserializationListener.h5
-rw-r--r--include/clang/Serialization/ASTReader.h427
-rw-r--r--include/clang/Serialization/ASTWriter.h121
-rw-r--r--include/clang/Serialization/GlobalModuleIndex.h7
-rw-r--r--include/clang/Serialization/Module.h42
-rw-r--r--include/clang/Serialization/ModuleManager.h6
-rw-r--r--include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h9
-rw-r--r--include/clang/StaticAnalyzer/Core/AnalyzerOptions.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h54
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/BugType.h32
-rw-r--r--include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h92
-rw-r--r--include/clang/StaticAnalyzer/Core/Checker.h21
-rw-r--r--include/clang/StaticAnalyzer/Core/CheckerManager.h26
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h12
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h268
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h31
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h26
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h14
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h76
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h236
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h28
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h10
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h8
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h6
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/Store.h5
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h2
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h67
-rw-r--r--include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h2
-rw-r--r--include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h49
-rw-r--r--include/clang/StaticAnalyzer/Frontend/FrontendActions.h4
-rw-r--r--include/clang/Tooling/ArgumentsAdjusters.h4
-rw-r--r--include/clang/Tooling/CommonOptionsParser.h16
-rw-r--r--include/clang/Tooling/CompilationDatabase.h16
-rw-r--r--include/clang/Tooling/FileMatchTrie.h4
-rw-r--r--include/clang/Tooling/JSONCompilationDatabase.h12
-rw-r--r--include/clang/Tooling/Refactoring.h15
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h6
-rw-r--r--include/clang/Tooling/ReplacementsYaml.h14
-rw-r--r--include/clang/Tooling/Tooling.h56
-rw-r--r--include/clang/module.modulemap110
315 files changed, 24693 insertions, 9741 deletions
diff --git a/include/clang/ARCMigrate/ARCMT.h b/include/clang/ARCMigrate/ARCMT.h
index 196f6c0b731f..ad4f23c604b3 100644
--- a/include/clang/ARCMigrate/ARCMT.h
+++ b/include/clang/ARCMigrate/ARCMT.h
@@ -113,7 +113,7 @@ public:
virtual void remove(CharSourceRange range) { }
};
- bool applyTransform(TransformFn trans, RewriteListener *listener = 0);
+ bool applyTransform(TransformFn trans, RewriteListener *listener = nullptr);
FileRemapper &getRemapper() { return Remapper; }
};
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h
index 45c8b4ed1a39..b3e74b996678 100644
--- a/include/clang/ARCMigrate/ARCMTActions.h
+++ b/include/clang/ARCMigrate/ARCMTActions.h
@@ -12,14 +12,14 @@
#include "clang/ARCMigrate/FileRemapper.h"
#include "clang/Frontend/FrontendAction.h"
-#include "llvm/ADT/OwningPtr.h"
+#include <memory>
namespace clang {
namespace arcmt {
class CheckAction : public WrapperFrontendAction {
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
CheckAction(FrontendAction *WrappedAction);
@@ -27,7 +27,7 @@ public:
class ModifyAction : public WrapperFrontendAction {
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
ModifyAction(FrontendAction *WrappedAction);
@@ -36,9 +36,9 @@ public:
class MigrateSourceAction : public ASTFrontendAction {
FileRemapper Remapper;
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
- StringRef InFile);
+ bool BeginInvocation(CompilerInstance &CI) override;
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
};
class MigrateAction : public WrapperFrontendAction {
@@ -46,7 +46,7 @@ class MigrateAction : public WrapperFrontendAction {
std::string PlistOut;
bool EmitPremigrationARCErros;
protected:
- virtual bool BeginInvocation(CompilerInstance &CI);
+ bool BeginInvocation(CompilerInstance &CI) override;
public:
MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
@@ -65,8 +65,9 @@ public:
unsigned migrateAction);
protected:
- virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
- virtual bool BeginInvocation(CompilerInstance &CI);
+ ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+ StringRef InFile) override;
+ bool BeginInvocation(CompilerInstance &CI) override;
};
}
diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h
index f7677cc8620a..e094301ae6c4 100644
--- a/include/clang/ARCMigrate/FileRemapper.h
+++ b/include/clang/ARCMigrate/FileRemapper.h
@@ -12,9 +12,9 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringRef.h"
+#include <memory>
namespace llvm {
class MemoryBuffer;
@@ -30,7 +30,7 @@ namespace arcmt {
class FileRemapper {
// FIXME: Reuse the same FileManager for multiple ASTContexts.
- OwningPtr<FileManager> FileMgr;
+ std::unique_ptr<FileManager> FileMgr;
typedef llvm::PointerUnion<const FileEntry *, llvm::MemoryBuffer *> Target;
typedef llvm::DenseMap<const FileEntry *, Target> MappingsTy;
@@ -56,8 +56,6 @@ public:
void applyMappings(PreprocessorOptions &PPOpts) const;
- void transferMappingsAndClear(PreprocessorOptions &PPOpts);
-
void clear(StringRef outputDir = StringRef());
private:
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h
index b4fd2affa653..e58c21923f51 100644
--- a/include/clang/AST/APValue.h
+++ b/include/clang/AST/APValue.h
@@ -80,7 +80,7 @@ private:
struct Vec {
APValue *Elts;
unsigned NumElts;
- Vec() : Elts(0), NumElts(0) {}
+ Vec() : Elts(nullptr), NumElts(0) {}
~Vec() { delete[] Elts; }
};
struct Arr {
@@ -108,34 +108,33 @@ private:
};
struct MemberPointerData;
- enum {
- MaxSize = (sizeof(ComplexAPSInt) > sizeof(ComplexAPFloat) ?
- sizeof(ComplexAPSInt) : sizeof(ComplexAPFloat))
- };
+ // We ensure elsewhere that Data is big enough for LV and MemberPointerData.
+ typedef llvm::AlignedCharArrayUnion<void *, APSInt, APFloat, ComplexAPSInt,
+ ComplexAPFloat, Vec, Arr, StructData,
+ UnionData, AddrLabelDiffData> DataType;
+ static const size_t DataSize = sizeof(DataType);
- union {
- void *Aligner;
- char Data[MaxSize];
- };
+ DataType Data;
public:
APValue() : Kind(Uninitialized) {}
- explicit APValue(const APSInt &I) : Kind(Uninitialized) {
- MakeInt(); setInt(I);
+ explicit APValue(APSInt I) : Kind(Uninitialized) {
+ MakeInt(); setInt(std::move(I));
}
- explicit APValue(const APFloat &F) : Kind(Uninitialized) {
- MakeFloat(); setFloat(F);
+ explicit APValue(APFloat F) : Kind(Uninitialized) {
+ MakeFloat(); setFloat(std::move(F));
}
explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
MakeVector(); setVector(E, N);
}
- APValue(const APSInt &R, const APSInt &I) : Kind(Uninitialized) {
- MakeComplexInt(); setComplexInt(R, I);
+ APValue(APSInt R, APSInt I) : Kind(Uninitialized) {
+ MakeComplexInt(); setComplexInt(std::move(R), std::move(I));
}
- APValue(const APFloat &R, const APFloat &I) : Kind(Uninitialized) {
- MakeComplexFloat(); setComplexFloat(R, I);
+ APValue(APFloat R, APFloat I) : Kind(Uninitialized) {
+ MakeComplexFloat(); setComplexFloat(std::move(R), std::move(I));
}
APValue(const APValue &RHS);
+ APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex)
: Kind(Uninitialized) {
MakeLValue(); setLValue(B, O, N, CallIndex);
@@ -200,7 +199,7 @@ public:
APSInt &getInt() {
assert(isInt() && "Invalid accessor");
- return *(APSInt*)(char*)Data;
+ return *(APSInt*)(char*)Data.buffer;
}
const APSInt &getInt() const {
return const_cast<APValue*>(this)->getInt();
@@ -208,7 +207,7 @@ public:
APFloat &getFloat() {
assert(isFloat() && "Invalid accessor");
- return *(APFloat*)(char*)Data;
+ return *(APFloat*)(char*)Data.buffer;
}
const APFloat &getFloat() const {
return const_cast<APValue*>(this)->getFloat();
@@ -216,7 +215,7 @@ public:
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data)->Real;
+ return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
}
const APSInt &getComplexIntReal() const {
return const_cast<APValue*>(this)->getComplexIntReal();
@@ -224,7 +223,7 @@ public:
APSInt &getComplexIntImag() {
assert(isComplexInt() && "Invalid accessor");
- return ((ComplexAPSInt*)(char*)Data)->Imag;
+ return ((ComplexAPSInt*)(char*)Data.buffer)->Imag;
}
const APSInt &getComplexIntImag() const {
return const_cast<APValue*>(this)->getComplexIntImag();
@@ -232,7 +231,7 @@ public:
APFloat &getComplexFloatReal() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data)->Real;
+ return ((ComplexAPFloat*)(char*)Data.buffer)->Real;
}
const APFloat &getComplexFloatReal() const {
return const_cast<APValue*>(this)->getComplexFloatReal();
@@ -240,7 +239,7 @@ public:
APFloat &getComplexFloatImag() {
assert(isComplexFloat() && "Invalid accessor");
- return ((ComplexAPFloat*)(char*)Data)->Imag;
+ return ((ComplexAPFloat*)(char*)Data.buffer)->Imag;
}
const APFloat &getComplexFloatImag() const {
return const_cast<APValue*>(this)->getComplexFloatImag();
@@ -259,20 +258,20 @@ public:
APValue &getVectorElt(unsigned I) {
assert(isVector() && "Invalid accessor");
assert(I < getVectorLength() && "Index out of range");
- return ((Vec*)(char*)Data)->Elts[I];
+ return ((Vec*)(char*)Data.buffer)->Elts[I];
}
const APValue &getVectorElt(unsigned I) const {
return const_cast<APValue*>(this)->getVectorElt(I);
}
unsigned getVectorLength() const {
assert(isVector() && "Invalid accessor");
- return ((const Vec*)(const void *)Data)->NumElts;
+ return ((const Vec*)(const void *)Data.buffer)->NumElts;
}
APValue &getArrayInitializedElt(unsigned I) {
assert(isArray() && "Invalid accessor");
assert(I < getArrayInitializedElts() && "Index out of range");
- return ((Arr*)(char*)Data)->Elts[I];
+ return ((Arr*)(char*)Data.buffer)->Elts[I];
}
const APValue &getArrayInitializedElt(unsigned I) const {
return const_cast<APValue*>(this)->getArrayInitializedElt(I);
@@ -283,35 +282,35 @@ public:
APValue &getArrayFiller() {
assert(isArray() && "Invalid accessor");
assert(hasArrayFiller() && "No array filler");
- return ((Arr*)(char*)Data)->Elts[getArrayInitializedElts()];
+ return ((Arr*)(char*)Data.buffer)->Elts[getArrayInitializedElts()];
}
const APValue &getArrayFiller() const {
return const_cast<APValue*>(this)->getArrayFiller();
}
unsigned getArrayInitializedElts() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data)->NumElts;
+ return ((const Arr*)(const void *)Data.buffer)->NumElts;
}
unsigned getArraySize() const {
assert(isArray() && "Invalid accessor");
- return ((const Arr*)(const void *)Data)->ArrSize;
+ return ((const Arr*)(const void *)Data.buffer)->ArrSize;
}
unsigned getStructNumBases() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data)->NumBases;
+ return ((const StructData*)(const char*)Data.buffer)->NumBases;
}
unsigned getStructNumFields() const {
assert(isStruct() && "Invalid accessor");
- return ((const StructData*)(const char*)Data)->NumFields;
+ return ((const StructData*)(const char*)Data.buffer)->NumFields;
}
APValue &getStructBase(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data)->Elts[i];
+ return ((StructData*)(char*)Data.buffer)->Elts[i];
}
APValue &getStructField(unsigned i) {
assert(isStruct() && "Invalid accessor");
- return ((StructData*)(char*)Data)->Elts[getStructNumBases() + i];
+ return ((StructData*)(char*)Data.buffer)->Elts[getStructNumBases() + i];
}
const APValue &getStructBase(unsigned i) const {
return const_cast<APValue*>(this)->getStructBase(i);
@@ -322,11 +321,11 @@ public:
const FieldDecl *getUnionField() const {
assert(isUnion() && "Invalid accessor");
- return ((const UnionData*)(const char*)Data)->Field;
+ return ((const UnionData*)(const char*)Data.buffer)->Field;
}
APValue &getUnionValue() {
assert(isUnion() && "Invalid accessor");
- return *((UnionData*)(char*)Data)->Value;
+ return *((UnionData*)(char*)Data.buffer)->Value;
}
const APValue &getUnionValue() const {
return const_cast<APValue*>(this)->getUnionValue();
@@ -338,41 +337,41 @@ public:
const AddrLabelExpr* getAddrLabelDiffLHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data)->LHSExpr;
+ return ((const AddrLabelDiffData*)(const char*)Data.buffer)->LHSExpr;
}
const AddrLabelExpr* getAddrLabelDiffRHS() const {
assert(isAddrLabelDiff() && "Invalid accessor");
- return ((const AddrLabelDiffData*)(const char*)Data)->RHSExpr;
+ return ((const AddrLabelDiffData*)(const char*)Data.buffer)->RHSExpr;
}
- void setInt(const APSInt &I) {
+ void setInt(APSInt I) {
assert(isInt() && "Invalid accessor");
- *(APSInt*)(char*)Data = I;
+ *(APSInt *)(char *)Data.buffer = std::move(I);
}
- void setFloat(const APFloat &F) {
+ void setFloat(APFloat F) {
assert(isFloat() && "Invalid accessor");
- *(APFloat*)(char*)Data = F;
+ *(APFloat *)(char *)Data.buffer = std::move(F);
}
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
- ((Vec*)(char*)Data)->Elts = new APValue[N];
- ((Vec*)(char*)Data)->NumElts = N;
+ ((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
+ ((Vec*)(char*)Data.buffer)->NumElts = N;
for (unsigned i = 0; i != N; ++i)
- ((Vec*)(char*)Data)->Elts[i] = E[i];
+ ((Vec*)(char*)Data.buffer)->Elts[i] = E[i];
}
- void setComplexInt(const APSInt &R, const APSInt &I) {
+ void setComplexInt(APSInt R, APSInt I) {
assert(R.getBitWidth() == I.getBitWidth() &&
"Invalid complex int (type mismatch).");
assert(isComplexInt() && "Invalid accessor");
- ((ComplexAPSInt*)(char*)Data)->Real = R;
- ((ComplexAPSInt*)(char*)Data)->Imag = I;
+ ((ComplexAPSInt *)(char *)Data.buffer)->Real = std::move(R);
+ ((ComplexAPSInt *)(char *)Data.buffer)->Imag = std::move(I);
}
- void setComplexFloat(const APFloat &R, const APFloat &I) {
+ void setComplexFloat(APFloat R, APFloat I) {
assert(&R.getSemantics() == &I.getSemantics() &&
"Invalid complex float (type mismatch).");
assert(isComplexFloat() && "Invalid accessor");
- ((ComplexAPFloat*)(char*)Data)->Real = R;
- ((ComplexAPFloat*)(char*)Data)->Imag = I;
+ ((ComplexAPFloat *)(char *)Data.buffer)->Real = std::move(R);
+ ((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
}
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
unsigned CallIndex);
@@ -381,13 +380,13 @@ public:
unsigned CallIndex);
void setUnion(const FieldDecl *Field, const APValue &Value) {
assert(isUnion() && "Invalid accessor");
- ((UnionData*)(char*)Data)->Field = Field;
- *((UnionData*)(char*)Data)->Value = Value;
+ ((UnionData*)(char*)Data.buffer)->Field = Field;
+ *((UnionData*)(char*)Data.buffer)->Value = Value;
}
void setAddrLabelDiff(const AddrLabelExpr* LHSExpr,
const AddrLabelExpr* RHSExpr) {
- ((AddrLabelDiffData*)(char*)Data)->LHSExpr = LHSExpr;
- ((AddrLabelDiffData*)(char*)Data)->RHSExpr = RHSExpr;
+ ((AddrLabelDiffData*)(char*)Data.buffer)->LHSExpr = LHSExpr;
+ ((AddrLabelDiffData*)(char*)Data.buffer)->RHSExpr = RHSExpr;
}
/// Assign by swapping from a copy of the RHS.
@@ -404,46 +403,46 @@ private:
}
void MakeInt() {
assert(isUninit() && "Bad state change");
- new ((void*)Data) APSInt(1);
+ new ((void*)Data.buffer) APSInt(1);
Kind = Int;
}
void MakeFloat() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) APFloat(0.0);
+ new ((void*)(char*)Data.buffer) APFloat(0.0);
Kind = Float;
}
void MakeVector() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) Vec();
+ new ((void*)(char*)Data.buffer) Vec();
Kind = Vector;
}
void MakeComplexInt() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) ComplexAPSInt();
+ new ((void*)(char*)Data.buffer) ComplexAPSInt();
Kind = ComplexInt;
}
void MakeComplexFloat() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) ComplexAPFloat();
+ new ((void*)(char*)Data.buffer) ComplexAPFloat();
Kind = ComplexFloat;
}
void MakeLValue();
void MakeArray(unsigned InitElts, unsigned Size);
void MakeStruct(unsigned B, unsigned M) {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) StructData(B, M);
+ new ((void*)(char*)Data.buffer) StructData(B, M);
Kind = Struct;
}
void MakeUnion() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) UnionData();
+ new ((void*)(char*)Data.buffer) UnionData();
Kind = Union;
}
void MakeMemberPointer(const ValueDecl *Member, bool IsDerivedMember,
ArrayRef<const CXXRecordDecl*> Path);
void MakeAddrLabelDiff() {
assert(isUninit() && "Bad state change");
- new ((void*)(char*)Data) AddrLabelDiffData();
+ new ((void*)(char*)Data.buffer) AddrLabelDiffData();
Kind = AddrLabelDiff;
}
};
diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h
index 7b6fa94b2043..736a10bec9b4 100644
--- a/include/clang/AST/ASTConsumer.h
+++ b/include/clang/AST/ASTConsumer.h
@@ -18,10 +18,10 @@
namespace clang {
class ASTContext;
+ class CXXMethodDecl;
class CXXRecordDecl;
class Decl;
class DeclGroupRef;
- class HandleTagDeclDefinition;
class ASTMutationListener;
class ASTDeserializationListener; // layering violation because void* is ugly
class SemaConsumer; // layering violation required for safe SemaConsumer
@@ -50,13 +50,15 @@ public:
virtual void Initialize(ASTContext &Context) {}
/// HandleTopLevelDecl - Handle the specified top-level declaration. This is
- /// called by the parser to process every top-level Decl*. Note that D can be
- /// the head of a chain of Decls (e.g. for `int a, b` the chain will have two
- /// elements). Use Decl::getNextDeclarator() to walk the chain.
+ /// called by the parser to process every top-level Decl*.
///
/// \returns true to continue parsing, or false to abort parsing.
virtual bool HandleTopLevelDecl(DeclGroupRef D);
+ /// \brief This callback is invoked each time an inline method definition is
+ /// completed.
+ virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {}
+
/// HandleInterestingDecl - Handle the specified interesting declaration. This
/// is called by the AST reader when deserializing things that might interest
/// the consumer. The default implementation forwards to HandleTopLevelDecl.
@@ -136,12 +138,12 @@ public:
/// \brief If the consumer is interested in entities getting modified after
/// their initial creation, it should return a pointer to
/// an ASTMutationListener here.
- virtual ASTMutationListener *GetASTMutationListener() { return 0; }
+ virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
/// \brief If the consumer is interested in entities being deserialized from
/// AST files, it should return a pointer to a ASTDeserializationListener here
virtual ASTDeserializationListener *GetASTDeserializationListener() {
- return 0;
+ return nullptr;
}
/// PrintStats - If desired, print any statistics.
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index f420e85ee146..8134f6b080b7 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -19,6 +19,7 @@
#include "clang/AST/CanonicalType.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/Decl.h"
+#include "clang/AST/ExternalASTSource.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RawCommentList.h"
@@ -33,10 +34,10 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
#include <vector>
namespace llvm {
@@ -51,7 +52,6 @@ namespace clang {
class CharUnits;
class DiagnosticsEngine;
class Expr;
- class ExternalASTSource;
class ASTMutationListener;
class IdentifierTable;
class MaterializeTemporaryExpr;
@@ -66,6 +66,7 @@ namespace clang {
class UnresolvedSetIterator;
class UsingDecl;
class UsingShadowDecl;
+ class VTableContextBase;
namespace Builtin { class Context; }
@@ -82,7 +83,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::FoldingSet<ExtQuals> ExtQualNodes;
mutable llvm::FoldingSet<ComplexType> ComplexTypes;
mutable llvm::FoldingSet<PointerType> PointerTypes;
- mutable llvm::FoldingSet<DecayedType> DecayedTypes;
+ mutable llvm::FoldingSet<AdjustedType> AdjustedTypes;
mutable llvm::FoldingSet<BlockPointerType> BlockPointerTypes;
mutable llvm::FoldingSet<LValueReferenceType> LValueReferenceTypes;
mutable llvm::FoldingSet<RValueReferenceType> RValueReferenceTypes;
@@ -364,6 +365,7 @@ private:
/// \brief Side-table of mangling numbers for declarations which rarely
/// need them (like static local vars).
llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers;
+ llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers;
/// \brief Mapping that stores parameterIndex values for ParmVarDecls when
/// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
@@ -392,7 +394,7 @@ private:
PartialDiagnostic::StorageAllocator DiagAllocator;
/// \brief The current C++ ABI.
- OwningPtr<CXXABI> ABI;
+ std::unique_ptr<CXXABI> ABI;
CXXABI *createCXXABI(const TargetInfo &T);
/// \brief The logical -> physical address space map.
@@ -415,14 +417,16 @@ public:
SelectorTable &Selectors;
Builtin::Context &BuiltinInfo;
mutable DeclarationNameTable DeclarationNames;
- OwningPtr<ExternalASTSource> ExternalSource;
+ IntrusiveRefCntPtr<ExternalASTSource> ExternalSource;
ASTMutationListener *Listener;
/// \brief Contains parents of a node.
- typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 1> ParentVector;
+ typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector;
/// \brief Maps from a node to its parents.
- typedef llvm::DenseMap<const void *, ParentVector> ParentMap;
+ typedef llvm::DenseMap<const void *,
+ llvm::PointerUnion<ast_type_traits::DynTypedNode *,
+ ParentVector *>> ParentMap;
/// \brief Returns the parents of the given node.
///
@@ -601,9 +605,9 @@ public:
///
/// \param OriginalDecl if not NULL, is set to declaration AST node that had
/// the comment, if the comment we found comes from a redeclaration.
- const RawComment *getRawCommentForAnyRedecl(
- const Decl *D,
- const Decl **OriginalDecl = NULL) const;
+ const RawComment *
+ getRawCommentForAnyRedecl(const Decl *D,
+ const Decl **OriginalDecl = nullptr) const;
/// Return parsed documentation comment attached to a given declaration.
/// Returns NULL if no comment is attached.
@@ -624,6 +628,43 @@ public:
private:
mutable comments::CommandTraits CommentCommandTraits;
+ /// \brief Iterator that visits import declarations.
+ class import_iterator {
+ ImportDecl *Import;
+
+ public:
+ typedef ImportDecl *value_type;
+ typedef ImportDecl *reference;
+ typedef ImportDecl *pointer;
+ typedef int difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ import_iterator() : Import() {}
+ explicit import_iterator(ImportDecl *Import) : Import(Import) {}
+
+ reference operator*() const { return Import; }
+ pointer operator->() const { return Import; }
+
+ import_iterator &operator++() {
+ Import = ASTContext::getNextLocalImport(Import);
+ return *this;
+ }
+
+ import_iterator operator++(int) {
+ import_iterator Other(*this);
+ ++(*this);
+ return Other;
+ }
+
+ friend bool operator==(import_iterator X, import_iterator Y) {
+ return X.Import == Y.Import;
+ }
+
+ friend bool operator!=(import_iterator X, import_iterator Y) {
+ return X.Import != Y.Import;
+ }
+ };
+
public:
comments::CommandTraits &getCommentCommandTraits() const {
return CommentCommandTraits;
@@ -710,47 +751,10 @@ public:
return Import->NextLocalImport;
}
- /// \brief Iterator that visits import declarations.
- class import_iterator {
- ImportDecl *Import;
-
- public:
- typedef ImportDecl *value_type;
- typedef ImportDecl *reference;
- typedef ImportDecl *pointer;
- typedef int difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- import_iterator() : Import() { }
- explicit import_iterator(ImportDecl *Import) : Import(Import) { }
-
- reference operator*() const { return Import; }
- pointer operator->() const { return Import; }
-
- import_iterator &operator++() {
- Import = ASTContext::getNextLocalImport(Import);
- return *this;
- }
-
- import_iterator operator++(int) {
- import_iterator Other(*this);
- ++(*this);
- return Other;
- }
-
- friend bool operator==(import_iterator X, import_iterator Y) {
- return X.Import == Y.Import;
- }
-
- friend bool operator!=(import_iterator X, import_iterator Y) {
- return X.Import != Y.Import;
- }
- };
-
- import_iterator local_import_begin() const {
- return import_iterator(FirstLocalImport);
+ typedef llvm::iterator_range<import_iterator> import_range;
+ import_range local_imports() const {
+ return import_range(import_iterator(FirstLocalImport), import_iterator());
}
- import_iterator local_import_end() const { return import_iterator(); }
Decl *getPrimaryMergedDecl(Decl *D) {
Decl *Result = MergedDecls.lookup(D);
@@ -797,11 +801,8 @@ public:
// The type is built when constructing 'BuiltinVaListDecl'.
mutable QualType VaListTagTy;
- ASTContext(LangOptions& LOpts, SourceManager &SM, const TargetInfo *t,
- IdentifierTable &idents, SelectorTable &sels,
- Builtin::Context &builtins,
- unsigned size_reserve,
- bool DelayInitialization = false);
+ ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents,
+ SelectorTable &sels, Builtin::Context &builtins);
~ASTContext();
@@ -810,11 +811,13 @@ public:
/// The external AST source provides the ability to load parts of
/// the abstract syntax tree as needed from some external storage,
/// e.g., a precompiled header.
- void setExternalSource(OwningPtr<ExternalASTSource> &Source);
+ void setExternalSource(IntrusiveRefCntPtr<ExternalASTSource> Source);
/// \brief Retrieve a pointer to the external AST source associated
/// with this AST context, if any.
- ExternalASTSource *getExternalSource() const { return ExternalSource.get(); }
+ ExternalASTSource *getExternalSource() const {
+ return ExternalSource.get();
+ }
/// \brief Attach an AST mutation listener to the AST context.
///
@@ -832,6 +835,14 @@ public:
void PrintStats() const;
const SmallVectorImpl<Type *>& getTypes() const { return Types; }
+ /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl
+ /// declaration.
+ RecordDecl *buildImplicitRecord(StringRef Name,
+ RecordDecl::TagKind TK = TTK_Struct) const;
+
+ /// \brief Create a new implicit TU-level typedef declaration.
+ TypedefDecl *buildImplicitTypedef(QualType T, StringRef Name) const;
+
/// \brief Retrieve the declaration for the 128-bit signed integer type.
TypedefDecl *getInt128Decl() const;
@@ -840,7 +851,7 @@ public:
/// \brief Retrieve the declaration for a 128-bit float stub type.
TypeDecl *getFloat128StubType() const;
-
+
//===--------------------------------------------------------------------===//
// Type Constructors
//===--------------------------------------------------------------------===//
@@ -915,6 +926,14 @@ public:
return CanQualType::CreateUnsafe(getPointerType((QualType) T));
}
+ /// \brief Return the uniqued reference to a type adjusted from the original
+ /// type to a new type.
+ QualType getAdjustedType(QualType Orig, QualType New) const;
+ CanQualType getAdjustedType(CanQualType Orig, CanQualType New) const {
+ return CanQualType::CreateUnsafe(
+ getAdjustedType((QualType)Orig, (QualType)New));
+ }
+
/// \brief Return the uniqued reference to the decayed version of the given
/// type. Can only be called on array and function types which decay to
/// pointer types.
@@ -1041,7 +1060,7 @@ public:
/// \brief Return the unique reference to the type for the specified type
/// declaration.
QualType getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl *PrevDecl = 0) const {
+ const TypeDecl *PrevDecl = nullptr) const {
assert(Decl && "Passed null for Decl param");
if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
@@ -1075,9 +1094,10 @@ public:
const TemplateTypeParmType *Replaced,
const TemplateArgument &ArgPack);
- QualType getTemplateTypeParmType(unsigned Depth, unsigned Index,
- bool ParameterPack,
- TemplateTypeParmDecl *ParmDecl = 0) const;
+ QualType
+ getTemplateTypeParmType(unsigned Depth, unsigned Index,
+ bool ParameterPack,
+ TemplateTypeParmDecl *ParmDecl = nullptr) const;
QualType getTemplateSpecializationType(TemplateName T,
const TemplateArgument *Args,
@@ -1121,11 +1141,18 @@ public:
Optional<unsigned> NumExpansions);
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
- ObjCInterfaceDecl *PrevDecl = 0) const;
+ ObjCInterfaceDecl *PrevDecl = nullptr) const;
QualType getObjCObjectType(QualType Base,
ObjCProtocolDecl * const *Protocols,
unsigned NumProtocols) const;
+
+ bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+ /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
+ /// QT's qualified-id protocol list adopt all protocols in IDecl's list
+ /// of protocols.
+ bool QIdProtocolsAdoptObjCObjectProtocols(QualType QT,
+ ObjCInterfaceDecl *IDecl);
/// \brief Return a ObjCObjectPointerType type for the given ObjCObjectType.
QualType getObjCObjectPointerType(QualType OIT) const;
@@ -1344,7 +1371,11 @@ public:
///
/// If \p Field is specified then record field names are also encoded.
void getObjCEncodingForType(QualType T, std::string &S,
- const FieldDecl *Field=0) const;
+ const FieldDecl *Field=nullptr) const;
+
+ /// \brief Emit the Objective-C property type encoding for the given
+ /// type \p T into \p S.
+ void getObjCEncodingForPropertyType(QualType T, std::string &S) const;
void getLegacyIntegralTypeEncoding(QualType &t) const;
@@ -1382,6 +1413,10 @@ public:
bool ProtocolCompatibleWithProtocol(ObjCProtocolDecl *lProto,
ObjCProtocolDecl *rProto) const;
+
+ ObjCPropertyImplDecl *getObjCPropertyImplDeclForPropertyDecl(
+ const ObjCPropertyDecl *PD,
+ const Decl *Container) const;
/// \brief Return the size of type \p T for Objective-C encoding purpose,
/// in characters.
@@ -1542,7 +1577,7 @@ public:
/// arguments to the builtin that are required to be integer constant
/// expressions.
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
- unsigned *IntegerConstantArgs = 0) const;
+ unsigned *IntegerConstantArgs = nullptr) const;
private:
CanQualType getFromTargetType(unsigned Type) const;
@@ -1704,6 +1739,8 @@ public:
bool isNearlyEmpty(const CXXRecordDecl *RD) const;
+ VTableContextBase *getVTableContext();
+
MangleContext *createMangleContext();
void DeepCollectObjCIvars(const ObjCInterfaceDecl *OI, bool leafClass,
@@ -1745,6 +1782,10 @@ public:
return getCanonicalType(T1) == getCanonicalType(T2);
}
+ bool hasSameType(const Type *T1, const Type *T2) const {
+ return getCanonicalType(T1) == getCanonicalType(T2);
+ }
+
/// \brief Return this type as a completely-unqualified array type,
/// capturing the qualifiers in \p Quals.
///
@@ -1994,9 +2035,9 @@ public:
bool Unqualified = false, bool BlockReturnType = false);
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false,
bool Unqualified = false);
- QualType mergeFunctionArgumentTypes(QualType, QualType,
- bool OfBlockPointer=false,
- bool Unqualified = false);
+ QualType mergeFunctionParameterTypes(QualType, QualType,
+ bool OfBlockPointer = false,
+ bool Unqualified = false);
QualType mergeTransparentUnionType(QualType, QualType,
bool OfBlockPointer=false,
bool Unqualified = false);
@@ -2008,7 +2049,7 @@ public:
const FunctionProtoType *ToFunctionType);
void ResetObjCLayout(const ObjCContainerDecl *CD) {
- ObjCLayouts[CD] = 0;
+ ObjCLayouts[CD] = nullptr;
}
//===--------------------------------------------------------------------===//
@@ -2027,14 +2068,12 @@ public:
//===--------------------------------------------------------------------===//
// Type Iterators.
//===--------------------------------------------------------------------===//
+ typedef llvm::iterator_range<SmallVectorImpl<Type *>::const_iterator>
+ type_const_range;
- typedef SmallVectorImpl<Type *>::iterator type_iterator;
- typedef SmallVectorImpl<Type *>::const_iterator const_type_iterator;
-
- type_iterator types_begin() { return Types.begin(); }
- type_iterator types_end() { return Types.end(); }
- const_type_iterator types_begin() const { return Types.begin(); }
- const_type_iterator types_end() const { return Types.end(); }
+ type_const_range types() const {
+ return type_const_range(Types.begin(), Types.end());
+ }
//===--------------------------------------------------------------------===//
// Integer Values
@@ -2125,7 +2164,7 @@ public:
/// when it is called.
void AddDeallocation(void (*Callback)(void*), void *Data);
- GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD);
+ GVALinkage GetGVALinkageForFunction(const FunctionDecl *FD) const;
GVALinkage GetGVALinkageForVariable(const VarDecl *VD);
/// \brief Determines if the decl can be CodeGen'ed or deserialized from PCH
@@ -2139,6 +2178,9 @@ public:
void setManglingNumber(const NamedDecl *ND, unsigned Number);
unsigned getManglingNumber(const NamedDecl *ND) const;
+ void setStaticLocalNumber(const VarDecl *VD, unsigned Number);
+ unsigned getStaticLocalNumber(const VarDecl *VD) const;
+
/// \brief Retrieve the context for computing mangling numbers in the given
/// DeclContext.
MangleNumberingContext &getManglingNumberContext(const DeclContext *DC);
@@ -2212,9 +2254,7 @@ public:
/// \brief Initialize built-in types.
///
/// This routine may only be invoked once for a given ASTContext object.
- /// It is normally invoked by the ASTContext constructor. However, the
- /// constructor can be asked to delay initialization, which places the burden
- /// of calling this function on the user of that object.
+ /// It is normally invoked after ASTContext construction.
///
/// \param Target The target
void InitBuiltinTypes(const TargetInfo &Target);
@@ -2238,17 +2278,21 @@ private:
void getObjCEncodingForStructureImpl(RecordDecl *RD, std::string &S,
const FieldDecl *Field,
bool includeVBases = true) const;
-
+public:
// Adds the encoding of a method parameter or return type.
void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
QualType T, std::string& S,
bool Extended) const;
+ /// \brief Returns true if this is an inline-initialized static data member
+ /// which is treated as a definition for MSVC compatibility.
+ bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
+
+private:
const ASTRecordLayout &
getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) const;
-private:
/// \brief A set of deallocations that should be performed when the
/// ASTContext is destroyed.
typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> >
@@ -2263,8 +2307,11 @@ private:
friend class DeclContext;
friend class DeclarationNameTable;
void ReleaseDeclContextMaps();
+ void ReleaseParentMapEntries();
- llvm::OwningPtr<ParentMap> AllParents;
+ std::unique_ptr<ParentMap> AllParents;
+
+ std::unique_ptr<VTableContextBase> VTContext;
};
/// \brief Utility function for constructing a nullary selector.
@@ -2363,4 +2410,18 @@ inline void operator delete[](void *Ptr, const clang::ASTContext &C, size_t) {
C.Deallocate(Ptr);
}
+/// \brief Create the representation of a LazyGenerationalUpdatePtr.
+template <typename Owner, typename T,
+ void (clang::ExternalASTSource::*Update)(Owner)>
+typename clang::LazyGenerationalUpdatePtr<Owner, T, Update>::ValueType
+ clang::LazyGenerationalUpdatePtr<Owner, T, Update>::makeValue(
+ const clang::ASTContext &Ctx, T Value) {
+ // Note, this is implemented here so that ExternalASTSource.h doesn't need to
+ // include ASTContext.h. We explicitly instantiate it for all relevant types
+ // in ASTContext.cpp.
+ if (auto *Source = Ctx.getExternalSource())
+ return new (Ctx) LazyData(Source, Value);
+ return Value;
+}
+
#endif
diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h
index 1635511984dc..484ca4cb8632 100644
--- a/include/clang/AST/ASTDiagnostic.h
+++ b/include/clang/AST/ASTDiagnostic.h
@@ -36,12 +36,9 @@ namespace clang {
void 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);
diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h
index b74c8ee1bf47..a335f980e6c5 100644
--- a/include/clang/AST/ASTImporter.h
+++ b/include/clang/AST/ASTImporter.h
@@ -278,7 +278,7 @@ namespace clang {
/// happens especially for anonymous structs. If the original of the second
/// RecordDecl can be found, we can complete it without the need for
/// importation, eliminating this loop.
- virtual Decl *GetOriginalDecl(Decl *To) { return NULL; }
+ virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
/// \brief Determine whether the given types are structurally
/// equivalent.
diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h
index 358ac7131e40..9af016b13d45 100644
--- a/include/clang/AST/ASTLambda.h
+++ b/include/clang/AST/ASTLambda.h
@@ -36,9 +36,9 @@ inline bool isLambdaCallOperator(const DeclContext *DC) {
return isLambdaCallOperator(cast<CXXMethodDecl>(DC));
}
-inline bool isGenericLambdaCallOperatorSpecialization(CXXMethodDecl *MD) {
+inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) {
if (!MD) return false;
- CXXRecordDecl *LambdaClass = MD->getParent();
+ const CXXRecordDecl *LambdaClass = MD->getParent();
if (LambdaClass && LambdaClass->isGenericLambda())
return isLambdaCallOperator(MD) &&
MD->isFunctionTemplateSpecialization();
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index 6d12a92c61bf..a89bfed53fbd 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -65,6 +65,10 @@ public:
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
const FunctionDecl *D) {}
+ /// \brief A function's exception specification has been evaluated or
+ /// instantiated.
+ virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
+
/// \brief A function's return type has been deduced.
virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
@@ -74,6 +78,9 @@ public:
/// \brief A static data member was implicitly instantiated.
virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+ /// \brief A function template's definition was instantiated.
+ virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
+
/// \brief A new objc category class was added for an interface.
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
const ObjCInterfaceDecl *IFD) {}
diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h
index 087ad5609001..0e06e26e6d80 100644
--- a/include/clang/AST/ASTTypeTraits.h
+++ b/include/clang/AST/ASTTypeTraits.h
@@ -57,11 +57,18 @@ public:
bool isSame(ASTNodeKind Other) const;
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
- bool isBaseOf(ASTNodeKind Other) const;
+ /// \param Distance If non-null, used to return the distance between \c this
+ /// and \c Other in the class hierarchy.
+ bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
/// \brief String representation of the kind.
StringRef asStringRef() const;
+ /// \brief Strict weak ordering for ASTNodeKind.
+ bool operator<(const ASTNodeKind &Other) const {
+ return KindId < Other.KindId;
+ }
+
private:
/// \brief Kind ids.
///
@@ -91,7 +98,9 @@ private:
/// \brief Returns \c true if \c Base is a base kind of (or same as) \c
/// Derived.
- static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
+ /// \param Distance If non-null, used to return the distance between \c Base
+ /// and \c Derived in the class hierarchy.
+ static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
/// \brief Helper meta-function to convert a kind T to its enum value.
///
@@ -133,6 +142,11 @@ KIND_TO_KIND_ID(Type)
#include "clang/AST/TypeNodes.def"
#undef KIND_TO_KIND_ID
+inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
+ OS << K.asStringRef();
+ return OS;
+}
+
/// \brief A dynamically typed AST node container.
///
/// Stores an AST node in a type safe way. This allows writing code that
@@ -198,8 +212,8 @@ public:
return getMemoizationData() < Other.getMemoizationData();
}
bool operator==(const DynTypedNode &Other) const {
- // Nodes with different types cannot be equal.
- if (!NodeKind.isSame(Other.NodeKind))
+ if (!NodeKind.isBaseOf(Other.NodeKind) &&
+ !Other.NodeKind.isBaseOf(NodeKind))
return false;
// FIXME: Implement for other types.
@@ -223,7 +237,7 @@ private:
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<BaseT>().isBaseOf(NodeKind))
return dyn_cast<T>(*reinterpret_cast<BaseT *const *>(Storage));
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const BaseT &Node) {
DynTypedNode Result;
@@ -238,7 +252,7 @@ private:
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return *reinterpret_cast<T *const *>(Storage);
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
@@ -253,7 +267,7 @@ private:
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
return reinterpret_cast<const T *>(Storage);
- return NULL;
+ return nullptr;
}
static DynTypedNode create(const T &Node) {
DynTypedNode Result;
@@ -283,18 +297,18 @@ private:
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Decl, T> >::type> : public DynCastPtrConverter<T, Decl> {};
+ T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type>
+ : public DynCastPtrConverter<T, Decl> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Stmt, T> >::type> : public DynCastPtrConverter<T, Stmt> {};
+ T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type>
+ : public DynCastPtrConverter<T, Stmt> {};
template <typename T>
struct DynTypedNode::BaseConverter<
- T, typename llvm::enable_if<llvm::is_base_of<
- Type, T> >::type> : public DynCastPtrConverter<T, Type> {};
+ T, typename std::enable_if<std::is_base_of<Type, T>::value>::type>
+ : public DynCastPtrConverter<T, Type> {};
template <>
struct DynTypedNode::BaseConverter<
@@ -341,7 +355,7 @@ inline const void *DynTypedNode::getMemoizationData() const {
} else if (ASTNodeKind::getFromNodeKind<NestedNameSpecifier>().isBaseOf(NodeKind)) {
return BaseConverter<NestedNameSpecifier>::get(NodeKind, Storage.buffer);
}
- return NULL;
+ return nullptr;
}
} // end namespace ast_type_traits
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index e8be67006c5b..84b0842492ad 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -32,9 +32,6 @@ class ASTUnresolvedSet {
DeclsTy Decls;
- ASTUnresolvedSet(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
- void operator=(const ASTUnresolvedSet &) LLVM_DELETED_FUNCTION;
-
friend class LazyASTUnresolvedSet;
public:
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 6db918eaa631..d92167e95992 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -26,30 +26,6 @@
#include <cstring>
#include <memory>
-#ifdef _MSC_VER
-namespace std {
-#if _MSC_VER <= 1310
- // Work around flawed VC++ implementation of std::uninitialized_copy. Define
- // additional overloads so that elements with pointer types are recognized as
- // scalars and not objects, causing bizarre type conversion errors.
- template<class T1, class T2>
- inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
- _Scalar_ptr_iterator_tag _Cat;
- return _Cat;
- }
-
- template<class T1, class T2>
- inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
- _Scalar_ptr_iterator_tag _Cat;
- return _Cat;
- }
-#else
- // FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
- // is that the above hack won't work if it wasn't fixed.
-#endif
-}
-#endif
-
namespace clang {
class ASTContext;
@@ -69,15 +45,30 @@ protected:
public:
// Default ctor - Initialize to empty.
- ASTVector() : Begin(0), End(0), Capacity(0, false) {}
+ ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+
+ ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
+ O.Begin = O.End = nullptr;
+ O.Capacity.setPointer(nullptr);
+ O.Capacity.setInt(false);
+ }
ASTVector(const ASTContext &C, unsigned N)
- : Begin(0), End(0), Capacity(0, false) {
+ : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
reserve(C, N);
}
+ ASTVector &operator=(ASTVector &&RHS) {
+ ASTVector O(std::move(RHS));
+ using std::swap;
+ swap(Begin, O.Begin);
+ swap(End, O.End);
+ swap(Capacity, O.Capacity);
+ return *this;
+ }
+
~ASTVector() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
// Destroy the constructed elements in the vector.
destroy_range(Begin, End);
}
@@ -147,7 +138,7 @@ public:
}
void clear() {
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
destroy_range(Begin, End);
}
End = Begin;
@@ -392,7 +383,7 @@ void ASTVector<T>::grow(const ASTContext &C, size_t MinSize) {
T *NewElts = new (C, llvm::alignOf<T>()) T[NewCapacity];
// Copy the elements over.
- if (llvm::is_class<T>::value) {
+ if (std::is_class<T>::value) {
std::uninitialized_copy(Begin, End, NewElts);
// Destroy the original elements.
destroy_range(Begin, End);
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index 7dbf41350a0f..fc4881619bce 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -26,8 +26,8 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
#include <cassert>
-#include <cstring>
namespace clang {
class ASTContext;
@@ -48,10 +48,9 @@ protected:
/// An index into the spelling list of an
/// attribute defined in Attr.td file.
unsigned SpellingListIndex : 4;
-
bool Inherited : 1;
-
bool IsPackExpansion : 1;
+ bool Implicit : 1;
virtual ~Attr();
@@ -76,7 +75,7 @@ public:
protected:
Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
: Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
- Inherited(false), IsPackExpansion(false) {}
+ Inherited(false), IsPackExpansion(false), Implicit(false) {}
public:
@@ -85,6 +84,7 @@ public:
}
unsigned getSpellingListIndex() const { return SpellingListIndex; }
+ virtual const char *getSpelling() const = 0;
SourceLocation getLocation() const { return Range.getBegin(); }
SourceRange getRange() const { return Range; }
@@ -92,6 +92,11 @@ public:
bool isInherited() const { return Inherited; }
+ /// \brief Returns true if the attribute has been implicitly created instead
+ /// of explicitly written by the user.
+ bool isImplicit() const { return Implicit; }
+ void setImplicit(bool I) { Implicit = I; }
+
void setPackExpansion(bool PE) { IsPackExpansion = PE; }
bool isPackExpansion() const { return IsPackExpansion; }
@@ -103,6 +108,11 @@ public:
// Pretty print this attribute.
virtual void printPretty(raw_ostream &OS,
const PrintingPolicy &Policy) const = 0;
+
+ /// \brief By default, attributes cannot be duplicated when being merged;
+ /// however, an attribute can override this. Returns true if the attribute
+ /// can be duplicated when merging.
+ virtual bool duplicatesAllowed() const { return false; }
};
class InheritableAttr : public Attr {
@@ -121,7 +131,7 @@ public:
};
class InheritableParamAttr : public InheritableAttr {
- virtual void anchor();
+ void anchor() override;
protected:
InheritableParamAttr(attr::Kind AK, SourceRange R,
unsigned SpellingListIndex = 0)
@@ -136,23 +146,21 @@ public:
}
};
-class MSInheritanceAttr : public InheritableAttr {
- virtual void anchor();
-protected:
- MSInheritanceAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
- : InheritableAttr(AK, R, SpellingListIndex) {}
-
-public:
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- // Relies on relative order of enum emission with respect to param attrs.
- return (A->getKind() <= attr::LAST_MS_INHERITANCE &&
- A->getKind() > attr::LAST_INHERITABLE_PARAM);
- }
-};
-
#include "clang/AST/Attrs.inc"
+inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+ const Attr *At) {
+ DB.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+ DiagnosticsEngine::ak_attr);
+ return DB;
+}
+
+inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
+ const Attr *At) {
+ PD.AddTaggedVal(reinterpret_cast<intptr_t>(At),
+ DiagnosticsEngine::ak_attr);
+ return PD;
+}
} // end namespace clang
#endif
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index 8bd8fbec895d..39ee81f1201c 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -43,7 +43,7 @@ typedef SmallVector<Attr*, 2> AttrVec;
typedef SmallVector<const Attr*, 2> ConstAttrVec;
/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
-/// providing attributes that are of a specifc type.
+/// providing attributes that are of a specific type.
template <typename SpecificAttr, typename Container = AttrVec>
class specific_attr_iterator {
typedef typename Container::const_iterator Iterator;
@@ -53,7 +53,7 @@ class specific_attr_iterator {
/// specifically requested, we don't necessarily advance this all the
/// way. Instead, we advance it when an operation is requested; if the
/// operation is acting on what should be a past-the-end iterator,
- /// then we offer no guarantees, but this way we do not dererence a
+ /// then we offer no guarantees, but this way we do not dereference a
/// past-the-end iterator when we move to a past-the-end position.
mutable Iterator Current;
@@ -98,7 +98,7 @@ public:
friend bool operator==(specific_attr_iterator Left,
specific_attr_iterator Right) {
- assert((Left.Current == 0) == (Right.Current == 0));
+ assert((Left.Current == nullptr) == (Right.Current == nullptr));
if (Left.Current < Right.Current)
Left.AdvanceToNext(Right.Current);
else
@@ -134,7 +134,7 @@ inline SpecificAttr *getSpecificAttr(const Container& container) {
if (i != specific_attr_end<SpecificAttr>(container))
return *i;
else
- return 0;
+ return nullptr;
}
} // end namespace clang
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index ba54fa2aa92b..260734f2200a 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -13,6 +13,11 @@ clang_tablegen(AttrDump.inc -gen-clang-attr-dump
SOURCE ../Basic/Attr.td
TARGET ClangAttrDump)
+clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+ SOURCE ../Basic/Attr.td
+ TARGET ClangAttrVisitor)
+
clang_tablegen(StmtNodes.inc -gen-clang-stmt-nodes
SOURCE ../Basic/StmtNodes.td
TARGET ClangStmtNodes)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index dbe4ad0f5a1d..37f6748ace90 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -177,8 +177,8 @@ public:
bool RecordPaths = true,
bool DetectVirtual = true)
: FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
- DetectVirtual(DetectVirtual), DetectedVirtual(0), DeclsFound(0),
- NumDeclsFound(0) { }
+ DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
+ DeclsFound(nullptr), NumDeclsFound(0) { }
~CXXBasePaths() { delete [] DeclsFound; }
@@ -190,8 +190,8 @@ public:
CXXBasePath& front() { return Paths.front(); }
const CXXBasePath& front() const { return Paths.front(); }
- decl_iterator found_decls_begin();
- decl_iterator found_decls_end();
+ typedef llvm::iterator_range<decl_iterator> decl_range;
+ decl_range found_decls();
/// \brief Determine whether the path from the most-derived type to the
/// given base type is ambiguous (i.e., it refers to multiple subobjects of
@@ -232,7 +232,8 @@ public:
/// \brief Uniquely identifies a virtual method within a class
/// hierarchy by the method itself and a class subobject number.
struct UniqueVirtualMethod {
- UniqueVirtualMethod() : Method(0), Subobject(0), InVirtualSubobject(0) { }
+ UniqueVirtualMethod()
+ : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
const CXXRecordDecl *InVirtualSubobject)
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 9c699b7e0ae2..7cccef69ddf8 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -17,7 +17,6 @@
#include "clang/AST/Type.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/type_traits.h"
#include <iterator>
namespace clang {
@@ -60,9 +59,9 @@ public:
/// \brief Converting constructor that permits implicit upcasting of
/// canonical type pointers.
- template<typename U>
- CanQual(const CanQual<U>& Other,
- typename llvm::enable_if<llvm::is_base_of<T, U>, int>::type = 0);
+ template <typename U>
+ CanQual(const CanQual<U> &Other,
+ typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
/// \brief Retrieve the underlying type pointer, which refers to a
/// canonical type.
@@ -541,39 +540,39 @@ struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> {
template<>
struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionNoProtoType>
: public CanProxyBase<FunctionNoProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
};
template<>
struct CanProxyAdaptor<FunctionProtoType>
: public CanProxyBase<FunctionProtoType> {
- LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType)
+ LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs)
- CanQualType getArgType(unsigned i) const {
- return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i));
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams)
+ CanQualType getParamType(unsigned i) const {
+ return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
}
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
- typedef CanTypeIterator<FunctionProtoType::arg_type_iterator>
- arg_type_iterator;
+ typedef CanTypeIterator<FunctionProtoType::param_type_iterator>
+ param_type_iterator;
- arg_type_iterator arg_type_begin() const {
- return arg_type_iterator(this->getTypePtr()->arg_type_begin());
+ param_type_iterator param_type_begin() const {
+ return param_type_iterator(this->getTypePtr()->param_type_begin());
}
- arg_type_iterator arg_type_end() const {
- return arg_type_iterator(this->getTypePtr()->arg_type_end());
+ param_type_iterator param_type_end() const {
+ return param_type_iterator(this->getTypePtr()->param_type_end());
}
// Note: canonical function types never have exception specifications
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 09ff6828ef5c..72ca9f5cd67d 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -165,7 +165,7 @@ namespace clang {
/// RoundUpToAlignment - Returns the next integer (mod 2**64) that is
/// greater than or equal to this quantity and is a multiple of \p Align.
/// Align must be non-zero.
- CharUnits RoundUpToAlignment(const CharUnits &Align) {
+ CharUnits RoundUpToAlignment(const CharUnits &Align) const {
return CharUnits(llvm::RoundUpToAlignment(Quantity,
Align.Quantity));
}
@@ -173,12 +173,7 @@ namespace clang {
/// Given that this is a non-zero alignment value, what is the
/// alignment at the given offset?
CharUnits alignmentAtOffset(CharUnits offset) {
- // alignment: 0010000
- // offset: 1011100
- // lowBits: 0001011
- // result: 0000100
- QuantityType lowBits = (Quantity-1) & (offset.Quantity-1);
- return CharUnits((lowBits + 1) & ~lowBits);
+ return CharUnits(llvm::MinAlign(Quantity, offset.Quantity));
}
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 28849f58a8ec..e18fe9ab86a0 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -100,16 +100,26 @@ protected:
};
enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
+ class HTMLTagCommentBitfields {
+ friend class HTMLTagComment;
+
+ unsigned : NumInlineContentCommentBits;
+
+ /// True if we found that this tag is malformed in some way.
+ unsigned IsMalformed : 1;
+ };
+ enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
+
class HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
- unsigned : NumInlineContentCommentBits;
+ unsigned : NumHTMLTagCommentBits;
/// True if this tag is self-closing (e. g., <br />). This is based on tag
/// spelling in comment (plain <br> would not set this flag).
unsigned IsSelfClosing : 1;
};
- enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
+ enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
class ParagraphCommentBitfields {
friend class ParagraphComment;
@@ -155,6 +165,7 @@ protected:
InlineContentCommentBitfields InlineContentCommentBits;
TextCommentBitfields TextCommentBits;
InlineCommandCommentBitfields InlineCommandCommentBits;
+ HTMLTagCommentBitfields HTMLTagCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
ParagraphCommentBitfields ParagraphCommentBits;
BlockCommandCommentBitfields BlockCommandCommentBits;
@@ -194,9 +205,9 @@ public:
const char *getCommentKindName() const;
- LLVM_ATTRIBUTE_USED void dump() const;
- LLVM_ATTRIBUTE_USED void dumpColor() const;
- LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
+ void dump() const;
+ void dumpColor() const;
+ void dump(const ASTContext &Context) const;
void dump(raw_ostream &OS, const CommandTraits *Traits,
const SourceManager *SM) const;
@@ -267,9 +278,9 @@ public:
return C->getCommentKind() == TextCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const LLVM_READONLY { return Text; }
@@ -325,9 +336,9 @@ public:
return C->getCommentKind() == InlineCommandCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
unsigned getCommandID() const {
return InlineCommandCommentBits.CommandID;
@@ -360,8 +371,7 @@ public:
};
/// Abstract class for opening and closing HTML tags. HTML tags are always
-/// treated as inline content (regardless HTML semantics); opening and closing
-/// tags are not matched.
+/// treated as inline content (regardless HTML semantics).
class HTMLTagComment : public InlineContentComment {
protected:
StringRef TagName;
@@ -377,6 +387,7 @@ protected:
TagName(TagName),
TagNameRange(TagNameBegin, TagNameEnd) {
setLocation(TagNameBegin);
+ HTMLTagCommentBits.IsMalformed = 0;
}
public:
@@ -392,6 +403,14 @@ public:
return SourceRange(L.getLocWithOffset(1),
L.getLocWithOffset(1 + TagName.size()));
}
+
+ bool isMalformed() const {
+ return HTMLTagCommentBits.IsMalformed;
+ }
+
+ void setIsMalformed() {
+ HTMLTagCommentBits.IsMalformed = 1;
+ }
};
/// An opening HTML tag with attributes.
@@ -450,9 +469,9 @@ public:
return C->getCommentKind() == HTMLStartTagCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
unsigned getNumAttrs() const {
return Attributes.size();
@@ -505,9 +524,9 @@ public:
return C->getCommentKind() == HTMLEndTagCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
};
/// Block content (contains inline content).
@@ -601,7 +620,7 @@ protected:
unsigned CommandID,
CommandMarkerKind CommandMarker) :
BlockContentComment(K, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -613,7 +632,7 @@ public:
unsigned CommandID,
CommandMarkerKind CommandMarker) :
BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
- Paragraph(NULL) {
+ Paragraph(nullptr) {
setLocation(getCommandNameBeginLoc());
BlockCommandCommentBits.CommandID = CommandID;
BlockCommandCommentBits.CommandMarker = CommandMarker;
@@ -699,7 +718,7 @@ private:
unsigned ParamIndex;
public:
- enum LLVM_ENUM_INT_TYPE(unsigned) {
+ enum : unsigned {
InvalidParamIndex = ~0U,
VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
};
@@ -861,9 +880,9 @@ public:
return C->getCommentKind() == VerbatimBlockLineCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const LLVM_READONLY {
return Text;
@@ -948,9 +967,9 @@ public:
return C->getCommentKind() == VerbatimLineCommentKind;
}
- child_iterator child_begin() const { return NULL; }
+ child_iterator child_begin() const { return nullptr; }
- child_iterator child_end() const { return NULL; }
+ child_iterator child_end() const { return nullptr; }
StringRef getText() const {
return Text;
@@ -981,9 +1000,9 @@ struct DeclInfo {
/// that we consider a "function".
ArrayRef<const ParmVarDecl *> ParamVars;
- /// Function result type if \c CommentDecl is something that we consider
+ /// Function return type if \c CommentDecl is something that we consider
/// a "function".
- QualType ResultType;
+ QualType ReturnType;
/// Template parameters that can be referenced by \\tparam if \c CommentDecl is
/// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
diff --git a/include/clang/AST/CommentCommands.td b/include/clang/AST/CommentCommands.td
index ed323daa9f8b..958ee032e71f 100644
--- a/include/clang/AST/CommentCommands.td
+++ b/include/clang/AST/CommentCommands.td
@@ -146,7 +146,7 @@ def Todo : BlockCommand<"todo">;
def Version : BlockCommand<"version">;
def Warning : BlockCommand<"warning">;
// HeaderDoc commands
-def Abstract : BlockCommand<"abstract">;
+def Abstract : BlockCommand<"abstract"> { let IsBriefCommand = 1; }
def ClassDesign : RecordLikeDetailCommand<"classdesign">;
def CoClass : RecordLikeDetailCommand<"coclass">;
def Dependency : RecordLikeDetailCommand<"dependency">;
diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td
index f98e32ddca4f..251490094940 100644
--- a/include/clang/AST/CommentHTMLTags.td
+++ b/include/clang/AST/CommentHTMLTags.td
@@ -52,3 +52,16 @@ def Tr : Tag<"tr"> { let EndTagOptional = 1; }
def Th : Tag<"th"> { let EndTagOptional = 1; }
def Td : Tag<"td"> { let EndTagOptional = 1; }
+// Define a blacklist of attributes that are not safe to pass through to HTML
+// output if the input is untrusted.
+//
+// FIXME: this should be a whitelist. When changing this to a whitelist, don't
+// forget to change the default in the TableGen backend.
+class Attribute<string spelling> {
+ string Spelling = spelling;
+ bit IsSafeToPassThrough = 1;
+}
+class EventHandlerContentAttribute<string spelling> : Attribute<spelling> {
+ let IsSafeToPassThrough = 0;
+}
+
diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h
index f152c778c9aa..a6e3ed89b27e 100644
--- a/include/clang/AST/CommentLexer.h
+++ b/include/clang/AST/CommentLexer.h
@@ -14,8 +14,8 @@
#ifndef LLVM_CLANG_AST_COMMENT_LEXER_H
#define LLVM_CLANG_AST_COMMENT_LEXER_H
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceManager.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -293,17 +293,7 @@ private:
StringRef resolveHTMLHexCharacterReference(StringRef Name) const;
void 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;
- }
+ tok::TokenKind Kind);
void formTextToken(Token &Result, const char *TokEnd) {
StringRef Text(BufferPtr, TokEnd - BufferPtr);
@@ -362,7 +352,7 @@ public:
StringRef getSpelling(const Token &Tok,
const SourceManager &SourceMgr,
- bool *Invalid = NULL) const;
+ bool *Invalid = nullptr) const;
};
} // end namespace comments
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 39109602b148..027c3b929df6 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -84,8 +84,8 @@ public:
T *Mem = Allocator.Allocate<T>(Size);
std::uninitialized_copy(Source.begin(), Source.end(), Mem);
return llvm::makeArrayRef(Mem, Size);
- } else
- return llvm::makeArrayRef(static_cast<T *>(NULL), 0);
+ }
+ return ArrayRef<T>();
}
ParagraphComment *actOnParagraphComment(
diff --git a/include/clang/AST/DataRecursiveASTVisitor.h b/include/clang/AST/DataRecursiveASTVisitor.h
new file mode 100644
index 000000000000..9ef008717b1b
--- /dev/null
+++ b/include/clang/AST/DataRecursiveASTVisitor.h
@@ -0,0 +1,2519 @@
+//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DataRecursiveASTVisitor interface, which recursively
+// traverses the entire AST, using data recursion for Stmts/Exprs.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H
+
+#include "clang/AST/Attr.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclFriend.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/TemplateName.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+
+// The following three macros are used for meta programming. The code
+// using them is responsible for defining macro OPERATOR().
+
+// All unary operators.
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
+ OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
+ OPERATOR(Extension)
+
+// All binary operators (excluding compound assign operators).
+#define BINOP_LIST() \
+ OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
+ OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
+ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
+ OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
+ OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
+
+// All compound assign operators.
+#define CAO_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+ OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+
+namespace clang {
+
+// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to
+// make it easier to track changes and keep the two in sync.
+#define RecursiveASTVisitor DataRecursiveASTVisitor
+
+// A helper macro to implement short-circuiting when recursing. It
+// invokes CALL_EXPR, which must be a method call, on the derived
+// object (s.t. a user of RecursiveASTVisitor can override the method
+// in CALL_EXPR).
+#define TRY_TO(CALL_EXPR) \
+ do { \
+ if (!getDerived().CALL_EXPR) \
+ return false; \
+ } while (0)
+
+/// \brief A class that does preorder depth-first traversal on the
+/// entire Clang AST and visits each node.
+///
+/// This class performs three distinct tasks:
+/// 1. traverse the AST (i.e. go to each node);
+/// 2. at a given node, walk up the class hierarchy, starting from
+/// the node's dynamic type, until the top-most class (e.g. Stmt,
+/// Decl, or Type) is reached.
+/// 3. given a (node, class) combination, where 'class' is some base
+/// class of the dynamic type of 'node', call a user-overridable
+/// function to actually visit the node.
+///
+/// These tasks are done by three groups of methods, respectively:
+/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
+/// for traversing an AST rooted at x. This method simply
+/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
+/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
+/// then recursively visits the child nodes of x.
+/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
+/// similarly.
+/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
+/// any child node of x. Instead, it first calls WalkUpFromBar(x)
+/// where Bar is the direct parent class of Foo (unless Foo has
+/// no parent), and then calls VisitFoo(x) (see the next list item).
+/// 3. VisitFoo(Foo *x) does task #3.
+///
+/// These three method groups are tiered (Traverse* > WalkUpFrom* >
+/// Visit*). A method (e.g. Traverse*) may call methods from the same
+/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
+/// It may not call methods from a higher tier.
+///
+/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
+/// is Foo's super class) before calling VisitFoo(), the result is
+/// that the Visit*() methods for a given node are called in the
+/// top-down order (e.g. for a node of type NamespaceDecl, the order will
+/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
+///
+/// This scheme guarantees that all Visit*() calls for the same AST
+/// node are grouped together. In other words, Visit*() methods for
+/// different nodes are never interleaved.
+///
+/// Stmts are traversed internally using a data queue to avoid a stack overflow
+/// with hugely nested ASTs.
+///
+/// Clients of this visitor should subclass the visitor (providing
+/// themselves as the template argument, using the curiously recurring
+/// template pattern) and override any of the Traverse*, WalkUpFrom*,
+/// and Visit* methods for declarations, types, statements,
+/// expressions, or other AST nodes where the visitor should customize
+/// behavior. Most users only need to override Visit*. Advanced
+/// users may override Traverse* and WalkUpFrom* to implement custom
+/// traversal strategies. Returning false from one of these overridden
+/// functions will abort the entire traversal.
+///
+/// By default, this visitor tries to visit every part of the explicit
+/// source code exactly once. The default policy towards templates
+/// is to descend into the 'pattern' class or function body, not any
+/// explicit or implicit instantiations. Explicit specializations
+/// are still visited, and the patterns of partial specializations
+/// are visited separately. This behavior can be changed by
+/// overriding shouldVisitTemplateInstantiations() in the derived class
+/// to return true, in which case all known implicit and explicit
+/// instantiations will be visited at the same time as the pattern
+/// from which they were produced.
+template <typename Derived> class RecursiveASTVisitor {
+public:
+ /// \brief Return a reference to the derived class.
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
+
+ /// \brief Return whether this visitor should recurse into
+ /// template instantiations.
+ bool shouldVisitTemplateInstantiations() const { return false; }
+
+ /// \brief Return whether this visitor should recurse into the types of
+ /// TypeLocs.
+ bool shouldWalkTypesOfTypeLocs() const { return true; }
+
+ /// \brief Recursively visit a statement or expression, by
+ /// dispatching to Traverse*() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is NULL).
+ bool TraverseStmt(Stmt *S);
+
+ /// \brief Recursively visit a type, by dispatching to
+ /// Traverse*Type() based on the argument's getTypeClass() property.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type).
+ bool TraverseType(QualType T);
+
+ /// \brief Recursively visit a type with location, by dispatching to
+ /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseTypeLoc(TypeLoc TL);
+
+ /// \brief Recursively visit an attribute, by dispatching to
+ /// Traverse*Attr() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseAttr(Attr *At);
+
+ /// \brief Recursively visit a declaration, by dispatching to
+ /// Traverse*Decl() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is NULL).
+ bool TraverseDecl(Decl *D);
+
+ /// \brief Recursively visit a C++ nested-name-specifier.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+
+ /// \brief Recursively visit a C++ nested-name-specifier with location
+ /// information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
+
+ /// \brief Recursively visit a name with its location information.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
+
+ /// \brief Recursively visit a template name and dispatch to the
+ /// appropriate method.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateName(TemplateName Template);
+
+ /// \brief Recursively visit a template argument and dispatch to the
+ /// appropriate method for the argument type.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: migrate callers to TemplateArgumentLoc instead.
+ bool TraverseTemplateArgument(const TemplateArgument &Arg);
+
+ /// \brief Recursively visit a template argument location and dispatch to the
+ /// appropriate method for the argument type.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
+
+ /// \brief Recursively visit a set of template arguments.
+ /// This can be overridden by a subclass, but it's not expected that
+ /// will be needed -- this visitor always dispatches to another.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
+ bool TraverseTemplateArguments(const TemplateArgument *Args,
+ unsigned NumArgs);
+
+ /// \brief Recursively visit a constructor initializer. This
+ /// automatically dispatches to another visitor for the initializer
+ /// expression, but not for the name of the initializer, so may
+ /// be overridden for clients that need access to the name.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
+
+ /// \brief Recursively visit a lambda capture.
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
+
+ /// \brief Recursively visit the body of a lambda expression.
+ ///
+ /// This provides a hook for visitors that need more context when visiting
+ /// \c LE->getBody().
+ ///
+ /// \returns false if the visitation was terminated early, true otherwise.
+ bool TraverseLambdaBody(LambdaExpr *LE);
+
+ // ---- Methods on Attrs ----
+
+ // \brief Visit an attribute.
+ bool VisitAttr(Attr *A) { return true; }
+
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
+#include "clang/AST/StmtNodes.inc"
+ // The above header #undefs ABSTRACT_STMT and STMT upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
+ bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
+ bool VisitStmt(Stmt *S) { return true; }
+#define STMT(CLASS, PARENT) \
+ bool WalkUpFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkUpFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
+ bool Visit##CLASS(CLASS *S) { return true; }
+#include "clang/AST/StmtNodes.inc"
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods. Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ bool TraverseUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ StmtQueue.queue(S->getSubExpr()); \
+ return true; \
+ } \
+ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##NAME(S)); \
+ return true; \
+ } \
+ bool VisitUnary##NAME(UnaryOperator *S) { return true; }
+
+ UNARYOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods. Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
+ bool TraverseBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFromBin##NAME(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ StmtQueue.queue(S->getLHS()); \
+ StmtQueue.queue(S->getRHS()); \
+ return true; \
+ } \
+ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
+ TRY_TO(VisitBin##NAME(S)); \
+ return true; \
+ } \
+ bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
+
+#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
+ BINOP_LIST()
+#undef OPERATOR
+
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods. Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
+
+ CAO_LIST()
+#undef OPERATOR
+#undef GENERAL_BINOP_FALLBACK
+
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
+
+// Declare Traverse*() for all concrete Type classes.
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
+#include "clang/AST/TypeNodes.def"
+ // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Type classes.
+ bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
+ bool VisitType(Type *T) { return true; }
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
+ TRY_TO(WalkUpFrom##BASE(T)); \
+ TRY_TO(Visit##CLASS##Type(T)); \
+ return true; \
+ } \
+ bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
+
+// Declare Traverse*() for all concrete TypeLoc classes.
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#include "clang/AST/TypeLocNodes.def"
+ // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
+ bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
+ bool VisitTypeLoc(TypeLoc TL) { return true; }
+
+ // QualifiedTypeLoc and UnqualTypeLoc are not declared in
+ // TypeNodes.def and thus need to be handled specially.
+ bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+ }
+ bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
+ bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
+ return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
+ }
+ bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
+
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
+ TRY_TO(Visit##CLASS##TypeLoc(TL)); \
+ return true; \
+ } \
+ bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
+#include "clang/AST/TypeNodes.def"
+
+// ---- Methods on Decls ----
+
+// Declare Traverse*() for all concrete Decl classes.
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#include "clang/AST/DeclNodes.inc"
+ // The above header #undefs ABSTRACT_DECL and DECL upon exit.
+
+ // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
+ bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
+ bool VisitDecl(Decl *D) { return true; }
+#define DECL(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
+ TRY_TO(WalkUpFrom##BASE(D)); \
+ TRY_TO(Visit##CLASS##Decl(D)); \
+ return true; \
+ } \
+ bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
+#include "clang/AST/DeclNodes.inc"
+
+private:
+ // These are helper methods used by more than one Traverse* method.
+ bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
+ bool TraverseClassInstantiations(ClassTemplateDecl *D);
+ bool TraverseVariableInstantiations(VarTemplateDecl *D);
+ bool TraverseFunctionInstantiations(FunctionTemplateDecl *D);
+ bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
+ unsigned Count);
+ bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
+ bool TraverseRecordHelper(RecordDecl *D);
+ bool TraverseCXXRecordHelper(CXXRecordDecl *D);
+ bool TraverseDeclaratorHelper(DeclaratorDecl *D);
+ bool TraverseDeclContextHelper(DeclContext *DC);
+ bool TraverseFunctionHelper(FunctionDecl *D);
+ bool TraverseVarHelper(VarDecl *D);
+ bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
+ bool TraverseOMPClause(OMPClause *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
+#include "clang/Basic/OpenMPKinds.def"
+ /// \brief Process clauses with list of variables.
+ template <typename T> bool VisitOMPClauseList(T *Node);
+
+ typedef SmallVector<Stmt *, 16> StmtsTy;
+ typedef SmallVector<StmtsTy *, 4> QueuesTy;
+
+ QueuesTy Queues;
+
+ class NewQueueRAII {
+ RecursiveASTVisitor &RAV;
+
+ public:
+ NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) {
+ RAV.Queues.push_back(&queue);
+ }
+ ~NewQueueRAII() { RAV.Queues.pop_back(); }
+ };
+
+ StmtsTy &getCurrentQueue() {
+ assert(!Queues.empty() && "base TraverseStmt was never called?");
+ return *Queues.back();
+ }
+
+public:
+ class StmtQueueAction {
+ StmtsTy &CurrQueue;
+
+ public:
+ explicit StmtQueueAction(RecursiveASTVisitor &RAV)
+ : CurrQueue(RAV.getCurrentQueue()) {}
+
+ void queue(Stmt *S) { CurrQueue.push_back(S); }
+ };
+};
+
+#define DISPATCH(NAME, CLASS, VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
+ if (!S)
+ return true;
+
+ StmtsTy Queue, StmtsToEnqueue;
+ Queue.push_back(S);
+ NewQueueRAII NQ(StmtsToEnqueue, *this);
+
+ while (!Queue.empty()) {
+ S = Queue.pop_back_val();
+ if (!S)
+ continue;
+
+ StmtsToEnqueue.clear();
+
+#define DISPATCH_STMT(NAME, CLASS, VAR) \
+ TRY_TO(Traverse##NAME(static_cast<CLASS *>(VAR))); \
+ break
+
+ // If we have a binary expr, dispatch to the subcode of the binop. A smart
+ // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
+ // below.
+ if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
+ switch (BinOp->getOpcode()) {
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
+
+ BINOP_LIST()
+#undef OPERATOR
+#undef BINOP_LIST
+
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
+ DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
+
+ CAO_LIST()
+#undef OPERATOR
+#undef CAO_LIST
+ }
+ } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
+ switch (UnOp->getOpcode()) {
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
+
+ UNARYOP_LIST()
+#undef OPERATOR
+#undef UNARYOP_LIST
+ }
+ } else {
+
+ // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
+ switch (S->getStmtClass()) {
+ case Stmt::NoStmtClass:
+ break;
+#define ABSTRACT_STMT(STMT)
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_STMT(CLASS, CLASS, S);
+#include "clang/AST/StmtNodes.inc"
+ }
+ }
+
+ for (SmallVectorImpl<Stmt *>::reverse_iterator RI = StmtsToEnqueue.rbegin(),
+ RE = StmtsToEnqueue.rend();
+ RI != RE; ++RI)
+ Queue.push_back(*RI);
+ }
+
+ return true;
+}
+
+#undef DISPATCH_STMT
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+ if (T.isNull())
+ return true;
+
+ switch (T->getTypeClass()) {
+#define ABSTRACT_TYPE(CLASS, BASE)
+#define TYPE(CLASS, BASE) \
+ case Type::CLASS: \
+ DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
+#include "clang/AST/TypeNodes.def"
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+ if (TL.isNull())
+ return true;
+
+ switch (TL.getTypeLocClass()) {
+#define ABSTRACT_TYPELOC(CLASS, BASE)
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+#include "clang/AST/TypeLocNodes.def"
+ }
+
+ return true;
+}
+
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
+ if (!D)
+ return true;
+
+ // As a syntax visitor, we want to ignore declarations for
+ // implicitly-defined declarations (ones not typed explicitly by the
+ // user).
+ if (D->isImplicit())
+ return true;
+
+ switch (D->getKind()) {
+#define ABSTRACT_DECL(DECL)
+#define DECL(CLASS, BASE) \
+ case Decl::CLASS: \
+ if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
+ return false; \
+ break;
+#include "clang/AST/DeclNodes.inc"
+ }
+
+ // Visit any attributes attached to this declaration.
+ for (auto *I : D->attrs()) {
+ if (!getDerived().TraverseAttr(I))
+ return false;
+ }
+ return true;
+}
+
+#undef DISPATCH
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
+ NestedNameSpecifier *NNS) {
+ if (!NNS)
+ return true;
+
+ if (NNS->getPrefix())
+ TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
+
+ switch (NNS->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Global:
+ return true;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
+ NestedNameSpecifierLoc NNS) {
+ if (!NNS)
+ return true;
+
+ if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+ TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+
+ switch (NNS.getNestedNameSpecifier()->getKind()) {
+ case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Namespace:
+ case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Global:
+ return true;
+
+ case NestedNameSpecifier::TypeSpec:
+ case NestedNameSpecifier::TypeSpecWithTemplate:
+ TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
+ break;
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
+ DeclarationNameInfo NameInfo) {
+ switch (NameInfo.getName().getNameKind()) {
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
+ TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
+
+ break;
+
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ break;
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
+ if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
+ TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
+ else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
+ TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
+ const TemplateArgument &Arg) {
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ return true;
+
+ case TemplateArgument::Type:
+ return getDerived().TraverseType(Arg.getAsType());
+
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ return getDerived().TraverseTemplateName(
+ Arg.getAsTemplateOrTemplatePattern());
+
+ case TemplateArgument::Expression:
+ return getDerived().TraverseStmt(Arg.getAsExpr());
+
+ case TemplateArgument::Pack:
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return true;
+}
+
+// FIXME: no template name location?
+// FIXME: no source locations for a template argument pack?
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
+ const TemplateArgumentLoc &ArgLoc) {
+ const TemplateArgument &Arg = ArgLoc.getArgument();
+
+ switch (Arg.getKind()) {
+ case TemplateArgument::Null:
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ case TemplateArgument::NullPtr:
+ return true;
+
+ case TemplateArgument::Type: {
+ // FIXME: how can TSI ever be NULL?
+ if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
+ return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
+ else
+ return getDerived().TraverseType(Arg.getAsType());
+ }
+
+ case TemplateArgument::Template:
+ case TemplateArgument::TemplateExpansion:
+ if (ArgLoc.getTemplateQualifierLoc())
+ TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
+ ArgLoc.getTemplateQualifierLoc()));
+ return getDerived().TraverseTemplateName(
+ Arg.getAsTemplateOrTemplatePattern());
+
+ case TemplateArgument::Expression:
+ return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
+
+ case TemplateArgument::Pack:
+ return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
+ Arg.pack_size());
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
+ const TemplateArgument *Args, unsigned NumArgs) {
+ for (unsigned I = 0; I != NumArgs; ++I) {
+ TRY_TO(TraverseTemplateArgument(Args[I]));
+ }
+
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
+ CXXCtorInitializer *Init) {
+ if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+
+ if (Init->isWritten())
+ TRY_TO(TraverseStmt(Init->getInit()));
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+ const LambdaCapture *C) {
+ if (C->isInitCapture())
+ TRY_TO(TraverseDecl(C->getCapturedVar()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(LE->getBody());
+ return true;
+}
+
+// ----------------- Type traversal -----------------
+
+// This macro makes available a variable T, the passed-in type.
+#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
+ TRY_TO(WalkUpFrom##TYPE(T)); \
+ { CODE; } \
+ return true; \
+ }
+
+DEF_TRAVERSE_TYPE(BuiltinType, {})
+
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(BlockPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(MemberPointerType, {
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseType(T->getPointeeType()));
+})
+
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
+
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(VariableArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
+
+DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
+
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+ { TRY_TO(TraverseType(T->getReturnType())); })
+
+DEF_TRAVERSE_TYPE(FunctionProtoType, {
+ TRY_TO(TraverseType(T->getReturnType()));
+
+ for (const auto &A : T->param_types()) {
+ TRY_TO(TraverseType(A));
+ }
+
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
+
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
+
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
+
+DEF_TRAVERSE_TYPE(DecltypeType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPE(UnaryTransformType, {
+ TRY_TO(TraverseType(T->getBaseType()));
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+})
+
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
+
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPE(AttributedType,
+ { TRY_TO(TraverseType(T->getModifiedType())); })
+
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
+
+DEF_TRAVERSE_TYPE(ElaboratedType, {
+ if (T->getQualifier()) {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ }
+ TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+ { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
+
+DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
+
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
+
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPE(ObjCObjectType, {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ TRY_TO(TraverseType(T->getBaseType()));
+})
+
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
+
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
+
+#undef DEF_TRAVERSE_TYPE
+
+// ----------------- TypeLoc traversal -----------------
+
+// This macro makes available a variable TL, the passed-in TypeLoc.
+// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
+// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
+// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
+// continue to work.
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ { CODE; } \
+ return true; \
+ }
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
+ // Move this over to the 'main' typeloc tree. Note that this is a
+ // move -- we pretend that we were really looking at the unqualified
+ // typeloc all along -- rather than a recursion, so we don't follow
+ // the normal CRTP plan of going through
+ // getDerived().TraverseTypeLoc. If we did, we'd be traversing
+ // twice for the same type (once as a QualifiedTypeLoc version of
+ // the type, once as an UnqualifiedTypeLoc version of the type),
+ // which in effect means we'd call VisitTypeLoc twice with the
+ // 'same' type. This solves that problem, at the cost of never
+ // seeing the qualified version of the type (unless the client
+ // subclasses TraverseQualifiedTypeLoc themselves). It's not a
+ // perfect solution. A perfect solution probably requires making
+ // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
+ // wrapper around Type* -- rather than being its own class in the
+ // type hierarchy.
+ return TraverseTypeLoc(TL.getUnqualifiedLoc());
+}
+
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
+
+// FIXME: ComplexTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ComplexType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(PointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+// FIXME: location of base class?
+// We traverse this in the type case as well, but how is it not reached through
+// the pointee type?
+DEF_TRAVERSE_TYPELOC(MemberPointerType, {
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+DEF_TRAVERSE_TYPELOC(DecayedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
+ // This isn't available for ArrayType, but is for the ArrayTypeLoc.
+ TRY_TO(TraverseStmt(TL.getSizeExpr()));
+ return true;
+}
+
+DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(VariableArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
+
+DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
+
+// FIXME: order? why not size expr first?
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(VectorType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+// FIXME: size and attributes
+// FIXME: base VectorTypeLoc is unfinished
+DEF_TRAVERSE_TYPELOC(ExtVectorType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
+
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+ { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
+
+// FIXME: location of exception specifications (attributes?)
+DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
+
+ const FunctionProtoType *T = TL.getTypePtr();
+
+ for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+ if (TL.getParam(I)) {
+ TRY_TO(TraverseDecl(TL.getParam(I)));
+ } else if (I < T->getNumParams()) {
+ TRY_TO(TraverseType(T->getParamType(I)));
+ }
+ }
+
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
+
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
+
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+ { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
+
+DEF_TRAVERSE_TYPELOC(TypeOfType, {
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+// FIXME: location of underlying expr
+DEF_TRAVERSE_TYPELOC(DecltypeType, {
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
+
+DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(AutoType, {
+ TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
+
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
+
+// FIXME: use the loc for the template name?
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+ TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
+
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
+
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ElaboratedType, {
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+ TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentNameType, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
+
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+ { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
+
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+ TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
+
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
+
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
+
+#undef DEF_TRAVERSE_TYPELOC
+
+// ----------------- Decl traversal -----------------
+//
+// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
+// the children that come from the DeclContext associated with it.
+// Therefore each Traverse* only needs to worry about children other
+// than those.
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
+ if (!DC)
+ return true;
+
+ for (auto *Child : DC->decls()) {
+ // BlockDecls and CapturedDecls are traversed through BlockExprs and
+ // CapturedStmts respectively.
+ if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
+ }
+
+ return true;
+}
+
+// This macro makes available a variable D, the passed-in decl.
+#define DEF_TRAVERSE_DECL(DECL, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
+ TRY_TO(WalkUpFrom##DECL(D)); \
+ { CODE; } \
+ TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
+ return true; \
+ }
+
+DEF_TRAVERSE_DECL(AccessSpecDecl, {})
+
+DEF_TRAVERSE_DECL(BlockDecl, {
+ if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+ TRY_TO(TraverseStmt(D->getBody()));
+ for (const auto &I : D->captures()) {
+ if (I.hasCopyExpr()) {
+ TRY_TO(TraverseStmt(I.getCopyExpr()));
+ }
+ }
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
+
+DEF_TRAVERSE_DECL(CapturedDecl, {
+ TRY_TO(TraverseStmt(D->getBody()));
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
+
+DEF_TRAVERSE_DECL(EmptyDecl, {})
+
+DEF_TRAVERSE_DECL(FileScopeAsmDecl,
+ { TRY_TO(TraverseStmt(D->getAsmString())); })
+
+DEF_TRAVERSE_DECL(ImportDecl, {})
+
+DEF_TRAVERSE_DECL(FriendDecl, {
+ // Friend is either decl or a type.
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+})
+
+DEF_TRAVERSE_DECL(FriendTemplateDecl, {
+ if (D->getFriendType())
+ TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
+ else
+ TRY_TO(TraverseDecl(D->getFriendDecl()));
+ for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+ TemplateParameterList *TPL = D->getTemplateParameterList(I);
+ for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
+ ITPL != ETPL; ++ITPL) {
+ TRY_TO(TraverseDecl(*ITPL));
+ }
+ }
+})
+
+DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl,
+ { TRY_TO(TraverseDecl(D->getSpecialization())); })
+
+DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
+
+DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
+ })
+
+DEF_TRAVERSE_DECL(StaticAssertDecl, {
+ TRY_TO(TraverseStmt(D->getAssertExpr()));
+ TRY_TO(TraverseStmt(D->getMessage()));
+})
+
+DEF_TRAVERSE_DECL(
+ TranslationUnitDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
+ // We shouldn't traverse an aliased namespace, since it will be
+ // defined (and, therefore, traversed) somewhere else.
+ //
+ // This return statement makes sure the traversal of nodes in
+ // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
+ // is skipped - don't remove it.
+ return true;
+})
+
+DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
+ })
+
+DEF_TRAVERSE_DECL(
+ NamespaceDecl,
+ {// Code in an unnamed namespace shows up automatically in
+ // decls_begin()/decls_end(). Thus we don't need to recurse on
+ // D->getAnonymousNamespace().
+ })
+
+DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
+ })
+
+DEF_TRAVERSE_DECL(ObjCMethodDecl, {
+ if (D->getReturnTypeSourceInfo()) {
+ TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
+ }
+ for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody()));
+ }
+ return true;
+})
+
+DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
+ if (D->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ else
+ TRY_TO(TraverseType(D->getType()));
+ return true;
+})
+
+DEF_TRAVERSE_DECL(UsingDecl, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_DECL(UsingShadowDecl, {})
+
+DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
+ for (auto *I : D->varlists()) {
+ TRY_TO(TraverseStmt(I));
+ }
+})
+
+// A helper method for TemplateDecl's children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
+ TemplateParameterList *TPL) {
+ if (TPL) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ return true;
+}
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations(
+ ClassTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ // We don't want to visit injected-class-names in this traversal.
+ if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
+ continue;
+
+ switch (
+ cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplateDecl, {
+ CXXRecordDecl *TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // class templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the class instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseClassInstantiations(D));
+
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the implicit instantiations of a
+// class template.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations(
+ VarTemplateDecl *D) {
+ for (auto *SD : D->specializations()) {
+ for (auto *RD : SD->redecls()) {
+ switch (
+ cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
+ // Visit the implicit instantiations with the requested pattern.
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // We don't need to do anything on an explicit instantiation
+ // or explicit specialization because there will be an explicit
+ // node for it elsewhere.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(VarTemplateDecl, {
+ VarDecl *TempDecl = D->getTemplatedDecl();
+ TRY_TO(TraverseDecl(TempDecl));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // variable templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the variable instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseVariableInstantiations(D));
+
+ // Note that getInstantiatedFromMemberTemplate() is just a link
+ // from a template instantiation back to the template from which
+ // it was instantiated, and thus should not be traversed.
+})
+
+// A helper method for traversing the instantiations of a
+// function while skipping its specializations.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations(
+ FunctionTemplateDecl *D) {
+ for (auto *FD : D->specializations()) {
+ for (auto *RD : FD->redecls()) {
+ switch (RD->getTemplateSpecializationKind()) {
+ case TSK_Undeclared:
+ case TSK_ImplicitInstantiation:
+ // We don't know what kind of FunctionDecl this is.
+ TRY_TO(TraverseDecl(RD));
+ break;
+
+ // No need to visit explicit instantiations, we'll find the node
+ // eventually.
+ // FIXME: This is incorrect; there is no other node for an explicit
+ // instantiation of a function template specialization.
+ case TSK_ExplicitInstantiationDeclaration:
+ case TSK_ExplicitInstantiationDefinition:
+ break;
+
+ case TSK_ExplicitSpecialization:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionTemplateDecl, {
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+
+ // By default, we do not traverse the instantiations of
+ // function templates since they do not appear in the user code. The
+ // following code optionally traverses them.
+ //
+ // We only traverse the function instantiations when we see the canonical
+ // declaration of the template, to ensure we only visit them once.
+ if (getDerived().shouldVisitTemplateInstantiations() &&
+ D == D->getCanonicalDecl())
+ TRY_TO(TraverseFunctionInstantiations(D));
+})
+
+DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
+ // D is the "T" in something like
+ // template <template <typename> class T> class container { };
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ if (D->hasDefaultArgument()) {
+ TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
+ }
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
+ // D is the "T" in something like "template<typename T> class vector;"
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+ if (D->hasDefaultArgument())
+ TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_DECL(TypedefDecl, {
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the typedef, not something that was written in the
+ // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasDecl, {
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type alias, not something that was written in the
+ // source.
+})
+
+DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
+ TRY_TO(TraverseDecl(D->getTemplatedDecl()));
+ TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
+})
+
+DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
+ // A dependent using declaration which was marked with 'typename'.
+ // template<class T> class A : public B<T> { using typename B<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the
+ // source.
+})
+
+DEF_TRAVERSE_DECL(EnumDecl, {
+ if (D->getTypeForDecl())
+ TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
+
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ // The enumerators are already traversed by
+ // decls_begin()/decls_end().
+})
+
+// Helper methods for RecordDecl and its children.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
+ // We shouldn't traverse D->getTypeForDecl(); it's a result of
+ // declaring the type, not something that was written in the source.
+
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
+ if (!TraverseRecordHelper(D))
+ return false;
+ if (D->isCompleteDefinition()) {
+ for (const auto &I : D->bases()) {
+ TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
+ }
+ // We don't traverse the friends or the conversions, as they are
+ // already in decls_begin()/decls_end().
+ }
+ return true;
+}
+
+DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
+
+DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, {
+ // For implicit instantiations ("set<int> x;"), we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere. (Note the instatiated *type* --
+ // set<int> -- is written, and will still get a callback of
+ // TemplateSpecializationType). For explicit instantiations
+ // ("template set<int>;"), we do need a callback, since this
+ // is the only callback that's made for this instantiation.
+ // We use getTypeAsWritten() to distinguish.
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+ if (!getDerived().shouldVisitTemplateInstantiations() &&
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ // Returning from here skips traversing the
+ // declaration context of the ClassTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro)
+ // which contains the instantiated members of the class.
+ return true;
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
+ const TemplateArgumentLoc *TAL, unsigned Count) {
+ for (unsigned I = 0; I < Count; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
+ }
+ return true;
+}
+
+DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, {
+ // The partial specialization.
+ if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ // The args that remains unspecialized.
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+ // Don't need the ClassTemplatePartialSpecializationHelper, even
+ // though that's our parent class -- we already visit all the
+ // template args here.
+ TRY_TO(TraverseCXXRecordHelper(D));
+
+ // Instantiations will have been visited with the primary template.
+})
+
+DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
+
+DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
+ // Like UnresolvedUsingTypenameDecl, but without the 'typename':
+ // template <class T> Class A : public Base<T> { using Base<T>::foo; };
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+})
+
+DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ if (D->getTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+ else
+ TRY_TO(TraverseType(D->getType()));
+ return true;
+}
+
+DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
+
+DEF_TRAVERSE_DECL(FieldDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ else if (D->hasInClassInitializer())
+ TRY_TO(TraverseStmt(D->getInClassInitializer()));
+})
+
+DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
+
+DEF_TRAVERSE_DECL(ObjCIvarDecl, {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ if (D->isBitField())
+ TRY_TO(TraverseStmt(D->getBitWidth()));
+ // FIXME: implement the rest.
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
+
+ // If we're an explicit template specialization, iterate over the
+ // template args that were explicitly specified. If we were doing
+ // this in typing order, we'd do it between the return type and
+ // the function args, but both are handled by the FunctionTypeLoc
+ // above, so we have to choose one side. I've decided to do before.
+ if (const FunctionTemplateSpecializationInfo *FTSI =
+ D->getTemplateSpecializationInfo()) {
+ if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
+ FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
+ // A specialization might not have explicit template arguments if it has
+ // a templated return type and concrete arguments.
+ if (const ASTTemplateArgumentListInfo *TALI =
+ FTSI->TemplateArgumentsAsWritten) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
+ TALI->NumTemplateArgs));
+ }
+ }
+ }
+
+ // Visit the function type itself, which can be either
+ // FunctionNoProtoType or FunctionProtoType, or a typedef. This
+ // also covers the return type and the function parameters,
+ // including exception specifications.
+ TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
+
+ if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+ // Constructor initializers.
+ for (auto *I : Ctor->inits()) {
+ TRY_TO(TraverseConstructorInitializer(I));
+ }
+ }
+
+ if (D->isThisDeclarationADefinition()) {
+ TRY_TO(TraverseStmt(D->getBody())); // Function body.
+ }
+ return true;
+}
+
+DEF_TRAVERSE_DECL(FunctionDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXMethodDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXConstructorDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
+
+// CXXConversionDecl is the declaration of a type conversion operator.
+// It's not a cast expression.
+DEF_TRAVERSE_DECL(CXXConversionDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
+
+DEF_TRAVERSE_DECL(CXXDestructorDecl, {
+ // We skip decls_begin/decls_end, which are already covered by
+ // TraverseFunctionHelper().
+ return TraverseFunctionHelper(D);
+})
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
+ TRY_TO(TraverseDeclaratorHelper(D));
+ // Default params are taken care of when we traverse the ParmVarDecl.
+ if (!isa<ParmVarDecl>(D))
+ TRY_TO(TraverseStmt(D->getInit()));
+ return true;
+}
+
+DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, {
+ // For implicit instantiations, we don't want to
+ // recurse at all, since the instatiated class isn't written in
+ // the source code anywhere.
+ if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+ TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
+
+ if (!getDerived().shouldVisitTemplateInstantiations() &&
+ D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)
+ // Returning from here skips traversing the
+ // declaration context of the VarTemplateSpecializationDecl
+ // (embedded in the DEF_TRAVERSE_DECL() macro).
+ return true;
+})
+
+DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, {
+ // The partial specialization.
+ if (TemplateParameterList *TPL = D->getTemplateParameters()) {
+ for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
+ I != E; ++I) {
+ TRY_TO(TraverseDecl(*I));
+ }
+ }
+ // The args that remains unspecialized.
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ D->getTemplateArgsAsWritten()->getTemplateArgs(),
+ D->getTemplateArgsAsWritten()->NumTemplateArgs));
+
+ // Don't need the VarTemplatePartialSpecializationHelper, even
+ // though that's our parent class -- we already visit all the
+ // template args here.
+ TRY_TO(TraverseVarHelper(D));
+
+ // Instantiations will have been visited with the primary
+ // template.
+})
+
+DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
+
+DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
+ // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
+ TRY_TO(TraverseDeclaratorHelper(D));
+ TRY_TO(TraverseStmt(D->getDefaultArgument()));
+})
+
+DEF_TRAVERSE_DECL(ParmVarDecl, {
+ TRY_TO(TraverseVarHelper(D));
+
+ if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
+
+ if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
+ !D->hasUnparsedDefaultArg())
+ TRY_TO(TraverseStmt(D->getDefaultArg()));
+})
+
+#undef DEF_TRAVERSE_DECL
+
+// ----------------- Stmt traversal -----------------
+//
+// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
+// over the children defined in children() (every stmt defines these,
+// though sometimes the range is empty). Each individual Traverse*
+// method only needs to worry about children other than those. To see
+// what children() does for a given class, see, e.g.,
+// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
+
+// This macro makes available a variable S, the passed-in stmt.
+#define DEF_TRAVERSE_STMT(STMT, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) { \
+ TRY_TO(WalkUpFrom##STMT(S)); \
+ StmtQueueAction StmtQueue(*this); \
+ { CODE; } \
+ for (Stmt::child_range range = S->children(); range; ++range) { \
+ StmtQueue.queue(*range); \
+ } \
+ return true; \
+ }
+
+DEF_TRAVERSE_STMT(GCCAsmStmt, {
+ StmtQueue.queue(S->getAsmString());
+ for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
+ StmtQueue.queue(S->getInputConstraintLiteral(I));
+ }
+ for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
+ StmtQueue.queue(S->getOutputConstraintLiteral(I));
+ }
+ for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
+ StmtQueue.queue(S->getClobberStringLiteral(I));
+ }
+ // children() iterates over inputExpr and outputExpr.
+})
+
+DEF_TRAVERSE_STMT(
+ MSAsmStmt,
+ {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
+ // added this needs to be implemented.
+ })
+
+DEF_TRAVERSE_STMT(CXXCatchStmt, {
+ TRY_TO(TraverseDecl(S->getExceptionDecl()));
+ // children() iterates over the handler block.
+})
+
+DEF_TRAVERSE_STMT(DeclStmt, {
+ for (auto *I : S->decls()) {
+ TRY_TO(TraverseDecl(I));
+ }
+ // Suppress the default iteration over children() by
+ // returning. Here's why: A DeclStmt looks like 'type var [=
+ // initializer]'. The decls above already traverse over the
+ // initializers, so we don't have to do it again (which
+ // children() would do).
+ return true;
+})
+
+// These non-expr stmts (most of them), do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BreakStmt, {})
+DEF_TRAVERSE_STMT(CXXTryStmt, {})
+DEF_TRAVERSE_STMT(CaseStmt, {})
+DEF_TRAVERSE_STMT(CompoundStmt, {})
+DEF_TRAVERSE_STMT(ContinueStmt, {})
+DEF_TRAVERSE_STMT(DefaultStmt, {})
+DEF_TRAVERSE_STMT(DoStmt, {})
+DEF_TRAVERSE_STMT(ForStmt, {})
+DEF_TRAVERSE_STMT(GotoStmt, {})
+DEF_TRAVERSE_STMT(IfStmt, {})
+DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
+DEF_TRAVERSE_STMT(LabelStmt, {})
+DEF_TRAVERSE_STMT(AttributedStmt, {})
+DEF_TRAVERSE_STMT(NullStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
+DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
+DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
+DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
+DEF_TRAVERSE_STMT(CXXForRangeStmt, {})
+DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+})
+DEF_TRAVERSE_STMT(ReturnStmt, {})
+DEF_TRAVERSE_STMT(SwitchStmt, {})
+DEF_TRAVERSE_STMT(WhileStmt, {})
+
+DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+DEF_TRAVERSE_STMT(DeclRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(
+ S->getExplicitTemplateArgs().getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+DEF_TRAVERSE_STMT(MemberExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+})
+
+DEF_TRAVERSE_STMT(
+ ImplicitCastExpr,
+ {// We don't traverse the cast type, as it's not written in the
+ // source code.
+ })
+
+DEF_TRAVERSE_STMT(CStyleCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXConstCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+
+// InitListExpr is a tricky one, because we want to do all our work on
+// the syntactic form of the listexpr, but this method takes the
+// semantic form by default. We can't use the macro helper because it
+// calls WalkUp*() on the semantic form, before our code can convert
+// to the syntactic form.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
+ if (InitListExpr *Syn = S->getSyntacticForm())
+ S = Syn;
+ TRY_TO(WalkUpFromInitListExpr(S));
+ StmtQueueAction StmtQueue(*this);
+ // All we need are the default actions. FIXME: use a helper function.
+ for (Stmt::child_range range = S->children(); range; ++range) {
+ StmtQueue.queue(*range);
+ }
+ return true;
+}
+
+// GenericSelectionExpr is a special case because the types and expressions
+// are interleaved. We also need to watch out for null types (default
+// generic associations).
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
+ GenericSelectionExpr *S) {
+ TRY_TO(WalkUpFromGenericSelectionExpr(S));
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(S->getControllingExpr());
+ for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
+ if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
+ TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
+ StmtQueue.queue(S->getAssocExpr(i));
+ }
+ return true;
+}
+
+// PseudoObjectExpr is a special case because of the wierdness with
+// syntactic expressions and opaque values.
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
+ TRY_TO(WalkUpFromPseudoObjectExpr(S));
+ StmtQueueAction StmtQueue(*this);
+ StmtQueue.queue(S->getSyntacticForm());
+ for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
+ e = S->semantics_end();
+ i != e; ++i) {
+ Expr *sub = *i;
+ if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
+ sub = OVE->getSourceExpr();
+ StmtQueue.queue(sub);
+ }
+ return true;
+}
+
+DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
+ // This is called for code like 'return T()' where T is a built-in
+ // (i.e. non-class) type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXNewExpr, {
+ // The child-iterator will pick up the other arguments.
+ TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(OffsetOfExpr, {
+ // The child-iterator will pick up the expression representing
+ // the field.
+ // FIMXE: for code like offsetof(Foo, a.b.c), should we get
+ // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isArgumentType())
+ TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTypeidExpr, {
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXUuidofExpr, {
+ // The child-iterator will pick up the arg if it's an expression,
+ // but not if it's a type.
+ if (S->isTypeOperand())
+ TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(TypeTraitExpr, {
+ for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
+ TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
+ TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(ExpressionTraitExpr,
+ { StmtQueue.queue(S->getQueriedExpression()); })
+
+DEF_TRAVERSE_STMT(VAArgExpr, {
+ // The child-iterator will pick up the expression argument.
+ TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
+})
+
+DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
+ // This is called for code like 'return T()' where T is a class type.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// Walk only the visible parts of lambda expressions.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
+ TRY_TO(WalkUpFromLambdaExpr(S));
+
+ for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
+ CEnd = S->explicit_capture_end();
+ C != CEnd; ++C) {
+ TRY_TO(TraverseLambdaCapture(S, C));
+ }
+
+ if (S->hasExplicitParameters() || S->hasExplicitResultType()) {
+ TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
+ if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
+ // Visit the whole type.
+ TRY_TO(TraverseTypeLoc(TL));
+ } else if (FunctionProtoTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
+ if (S->hasExplicitParameters()) {
+ // Visit parameters.
+ for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
+ TRY_TO(TraverseDecl(Proto.getParam(I)));
+ }
+ } else {
+ TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
+ }
+ }
+ }
+
+ TRY_TO(TraverseLambdaBody(S));
+ return true;
+}
+
+DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
+ // This is called for code like 'T()', where T is a template argument.
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+
+// These expressions all might take explicit template arguments.
+// We traverse those if so. FIXME: implement these.
+DEF_TRAVERSE_STMT(CXXConstructExpr, {})
+DEF_TRAVERSE_STMT(CallExpr, {})
+DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
+
+// These exprs (most of them), do not need any action except iterating
+// over the children.
+DEF_TRAVERSE_STMT(AddrLabelExpr, {})
+DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
+DEF_TRAVERSE_STMT(BlockExpr, {
+ TRY_TO(TraverseDecl(S->getBlockDecl()));
+ return true; // no child statements to loop through.
+})
+DEF_TRAVERSE_STMT(ChooseExpr, {})
+DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
+DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
+DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
+DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
+DEF_TRAVERSE_STMT(ExprWithCleanups, {})
+DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
+DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
+DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
+ TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
+ if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
+ TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(CXXThisExpr, {})
+DEF_TRAVERSE_STMT(CXXThrowExpr, {})
+DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
+DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
+DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
+DEF_TRAVERSE_STMT(GNUNullExpr, {})
+DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
+DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
+DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
+ if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
+DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCMessageExpr, {
+ if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
+ TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
+DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
+DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
+DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
+DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
+ TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
+})
+DEF_TRAVERSE_STMT(ParenExpr, {})
+DEF_TRAVERSE_STMT(ParenListExpr, {})
+DEF_TRAVERSE_STMT(PredefinedExpr, {})
+DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
+DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
+DEF_TRAVERSE_STMT(StmtExpr, {})
+DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
+ TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
+ if (S->hasExplicitTemplateArgs()) {
+ TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
+ S->getNumTemplateArgs()));
+ }
+})
+
+DEF_TRAVERSE_STMT(SEHTryStmt, {})
+DEF_TRAVERSE_STMT(SEHExceptStmt, {})
+DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
+DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
+DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
+
+DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
+DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
+DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
+
+// These operators (all of them) do not need any action except
+// iterating over the children.
+DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
+DEF_TRAVERSE_STMT(ConditionalOperator, {})
+DEF_TRAVERSE_STMT(UnaryOperator, {})
+DEF_TRAVERSE_STMT(BinaryOperator, {})
+DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
+DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
+DEF_TRAVERSE_STMT(PackExpansionExpr, {})
+DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
+DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
+DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
+DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
+DEF_TRAVERSE_STMT(AtomicExpr, {})
+
+// These literals (all of them) do not need any action.
+DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(CharacterLiteral, {})
+DEF_TRAVERSE_STMT(FloatingLiteral, {})
+DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
+DEF_TRAVERSE_STMT(StringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
+DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
+DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
+
+// Traverse OpenCL: AsType, Convert.
+DEF_TRAVERSE_STMT(AsTypeExpr, {})
+
+// OpenMP directives.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
+ OMPExecutableDirective *S) {
+ for (auto *C : S->clauses()) {
+ TRY_TO(TraverseOMPClause(C));
+ }
+ return true;
+}
+
+DEF_TRAVERSE_STMT(OMPParallelDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSimdDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPForDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSectionDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPSingleDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPMasterDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPCriticalDirective, {
+ TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
+ TRY_TO(TraverseOMPExecutableDirective(S));
+})
+
+DEF_TRAVERSE_STMT(OMPParallelForDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPBarrierDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+DEF_TRAVERSE_STMT(OMPFlushDirective,
+ { TRY_TO(TraverseOMPExecutableDirective(S)); })
+
+// OpenMP clauses.
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
+ if (!C)
+ return true;
+ switch (C->getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ TRY_TO(Visit##Class(static_cast<Class *>(C))); \
+ break;
+#include "clang/Basic/OpenMPKinds.def"
+ case OMPC_threadprivate:
+ case OMPC_unknown:
+ break;
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
+ TRY_TO(TraverseStmt(C->getCondition()));
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
+ TRY_TO(TraverseStmt(C->getNumThreads()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
+ TRY_TO(TraverseStmt(C->getSafelen()));
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
+ TRY_TO(TraverseStmt(C->getNumForLoops()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
+ TRY_TO(TraverseStmt(C->getChunkSize()));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
+ return true;
+}
+
+template <typename Derived>
+template <typename T>
+bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
+ for (auto *E : Node->varlists()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
+ OMPFirstprivateClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
+ OMPLastprivateClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
+ TRY_TO(TraverseStmt(C->getStep()));
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
+ TRY_TO(TraverseStmt(C->getAlignment()));
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
+ OMPCopyprivateClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
+ TRY_TO(VisitOMPClauseList(C));
+ return true;
+}
+
+// FIXME: look at the following tricky-seeming exprs to see if we
+// need to recurse on anything. These are ones that have methods
+// returning decls or qualtypes or nestednamespecifier -- though I'm
+// not sure if they own them -- or just seemed very complicated, or
+// had lots of sub-types to explore.
+//
+// VisitOverloadExpr and its children: recurse on template args? etc?
+
+// FIXME: go through all the stmts and exprs again, and see which of them
+// create new types, and recurse on the types (TypeLocs?) of those.
+// Candidates:
+//
+// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
+// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
+// Every class that has getQualifier.
+
+#undef DEF_TRAVERSE_STMT
+
+#undef TRY_TO
+
+#undef RecursiveASTVisitor
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 244a7b8d400c..ce8b8b7dbcd6 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -21,6 +21,7 @@
#include "clang/AST/Redeclarable.h"
#include "clang/AST/Type.h"
#include "clang/Basic/Linkage.h"
+#include "clang/Basic/OperatorKinds.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/Compiler.h"
@@ -51,8 +52,7 @@ class VarTemplateDecl;
/// A client can read the relevant info using TypeLoc wrappers, e.g:
/// @code
/// TypeLoc TL = TypeSourceInfo->getTypeLoc();
-/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL))
-/// PL->getStarLoc().print(OS, SrcMgr);
+/// TL.getStartLoc().print(OS, SrcMgr);
/// @endcode
///
class TypeSourceInfo {
@@ -79,9 +79,9 @@ class TranslationUnitDecl : public Decl, public DeclContext {
NamespaceDecl *AnonymousNamespace;
explicit TranslationUnitDecl(ASTContext &ctx)
- : Decl(TranslationUnit, 0, SourceLocation()),
+ : Decl(TranslationUnit, nullptr, SourceLocation()),
DeclContext(TranslationUnit),
- Ctx(ctx), AnonymousNamespace(0) {}
+ Ctx(ctx), AnonymousNamespace(nullptr) {}
public:
ASTContext &getASTContext() const { return Ctx; }
@@ -110,7 +110,7 @@ class NamedDecl : public Decl {
DeclarationName Name;
private:
- NamedDecl *getUnderlyingDeclImpl();
+ NamedDecl *getUnderlyingDeclImpl() LLVM_READONLY;
protected:
NamedDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName N)
@@ -161,9 +161,8 @@ public:
void printQualifiedName(raw_ostream &OS) const;
void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
- // FIXME: Remove string versions.
+ // FIXME: Remove string version.
std::string getQualifiedNameAsString() const;
- std::string getQualifiedNameAsString(const PrintingPolicy &Policy) const;
/// getNameForDiagnostic - Appends a human-readable name for this
/// declaration into the given stream.
@@ -204,9 +203,8 @@ public:
// C++0x [class.mem]p1:
// The enumerators of an unscoped enumeration defined in
// the class are members of the class.
- // FIXME: support C++0x scoped enumerations.
if (isa<EnumDecl>(DC))
- DC = DC->getParent();
+ DC = DC->getRedeclContext();
return DC->isRecord();
}
@@ -259,6 +257,16 @@ public:
/// checking. Should always return true.
bool isLinkageValid() const;
+ /// \brief True if something has required us to compute the linkage
+ /// of this declaration.
+ ///
+ /// Language features which can retroactively change linkage (like a
+ /// typedef name for linkage purposes) may need to consider this,
+ /// but hopefully only in transitory ways during parsing.
+ bool hasLinkageBeenComputed() const {
+ return hasCachedLinkage();
+ }
+
/// \brief Looks through UsingDecls and ObjCCompatibleAliasDecls for
/// the underlying named decl.
NamedDecl *getUnderlyingDecl() {
@@ -295,7 +303,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const NamedDecl &ND) {
/// location of the statement. For GNU local labels (__label__), the decl
/// location is where the __label__ is.
class LabelDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
LabelStmt *TheStmt;
/// LocStart - For normal labels, this is the same as the main declaration
/// label, i.e., the location of the identifier; for GNU local labels,
@@ -320,7 +328,7 @@ public:
bool isGnuLocal() const { return LocStart != getLocation(); }
void setLocStart(SourceLocation L) { LocStart = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(LocStart, getLocation());
}
@@ -333,8 +341,6 @@ public:
class NamespaceDecl : public NamedDecl, public DeclContext,
public Redeclarable<NamespaceDecl>
{
- virtual void anchor();
-
/// LocStart - The starting location of the source range, pointing
/// to either the namespace or the inline keyword.
SourceLocation LocStart;
@@ -347,21 +353,15 @@ class NamespaceDecl : public NamedDecl, public DeclContext,
/// boolean value indicating whether this is an inline namespace.
llvm::PointerIntPair<NamespaceDecl *, 1, bool> AnonOrFirstNamespaceAndInline;
- NamespaceDecl(DeclContext *DC, bool Inline, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- NamespaceDecl *PrevDecl);
-
+ NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, NamespaceDecl *PrevDecl);
+
typedef Redeclarable<NamespaceDecl> redeclarable_base;
- virtual NamespaceDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
- }
- virtual NamespaceDecl *getPreviousDeclImpl() {
- return getPreviousDecl();
- }
- virtual NamespaceDecl *getMostRecentDeclImpl() {
- return getMostRecentDecl();
- }
-
+ NamespaceDecl *getNextRedeclarationImpl() override;
+ NamespaceDecl *getPreviousDeclImpl() override;
+ NamespaceDecl *getMostRecentDeclImpl() override;
+
public:
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
bool Inline, SourceLocation StartLoc,
@@ -370,9 +370,11 @@ public:
static NamespaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -432,14 +434,14 @@ public:
}
/// Retrieves the canonical declaration of this namespace.
- NamespaceDecl *getCanonicalDecl() {
+ NamespaceDecl *getCanonicalDecl() override {
return getOriginalNamespace();
}
const NamespaceDecl *getCanonicalDecl() const {
return getOriginalNamespace();
}
-
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(LocStart, RBraceLoc);
}
@@ -466,7 +468,7 @@ public:
/// an lvalue) a function (in which case it is a function designator) or
/// an enum constant.
class ValueDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
QualType DeclType;
protected:
@@ -505,7 +507,8 @@ struct QualifierInfo {
TemplateParameterList** TemplParamLists;
/// Default constructor.
- QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
+ QualifierInfo()
+ : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(nullptr) {}
/// setTemplateParameterListsInfo - Sets info about "outer" template
/// parameter lists.
@@ -567,7 +570,7 @@ public:
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY {
return getOuterLocStart();
}
@@ -576,7 +579,7 @@ public:
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : 0;
+ : nullptr;
}
/// \brief Retrieve the nested-name-specifier (with source-location
@@ -764,23 +767,27 @@ protected:
ParmVarDeclBitfields ParmVarDeclBits;
};
- VarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ VarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo, StorageClass SC);
typedef Redeclarable<VarDecl> redeclarable_base;
- virtual VarDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual VarDecl *getPreviousDeclImpl() {
+ VarDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
+ VarDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual VarDecl *getMostRecentDeclImpl() {
+ VarDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -791,8 +798,8 @@ public:
StorageClass S);
static VarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Returns the storage class as written in the source. For the
/// computed linkage of symbol, see getLinkage.
@@ -803,22 +810,12 @@ public:
void setTSCSpec(ThreadStorageClassSpecifier TSC) {
VarDeclBits.TSCSpec = TSC;
+ assert(VarDeclBits.TSCSpec == TSC && "truncation");
}
ThreadStorageClassSpecifier getTSCSpec() const {
return static_cast<ThreadStorageClassSpecifier>(VarDeclBits.TSCSpec);
}
- TLSKind getTLSKind() const {
- switch (VarDeclBits.TSCSpec) {
- case TSCS_unspecified:
- 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!");
- }
+ TLSKind getTLSKind() const;
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
@@ -827,6 +824,10 @@ public:
// Second check is for C++11 [dcl.stc]p4.
return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
+ // Global Named Register (GNU extension)
+ if (getStorageClass() == SC_Register && !isLocalVarDecl())
+ return false;
+
// Return true for: Auto, Register.
// Return false for: Extern, Static, PrivateExtern, OpenCLWorkGroupLocal.
@@ -913,7 +914,7 @@ public:
return getKind() != Decl::ParmVar && getDeclContext()->isRecord();
}
- virtual VarDecl *getCanonicalDecl();
+ VarDecl *getCanonicalDecl() override;
const VarDecl *getCanonicalDecl() const {
return const_cast<VarDecl*>(this)->getCanonicalDecl();
}
@@ -960,7 +961,7 @@ public:
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a static data member.
- virtual bool isOutOfLine() const;
+ bool isOutOfLine() const override;
/// \brief If this is a static data member, find its out-of-line definition.
VarDecl *getOutOfLineDefinition();
@@ -996,7 +997,7 @@ public:
}
const Expr *getInit() const {
if (Init.isNull())
- return 0;
+ return nullptr;
const Stmt *S = Init.dyn_cast<Stmt *>();
if (!S) {
@@ -1007,7 +1008,7 @@ public:
}
Expr *getInit() {
if (Init.isNull())
- return 0;
+ return nullptr;
Stmt *S = Init.dyn_cast<Stmt *>();
if (!S) {
@@ -1058,7 +1059,7 @@ public:
if (Eval->WasEvaluated)
return &Eval->Evaluated;
- return 0;
+ return nullptr;
}
/// \brief Determines whether it is already known whether the
@@ -1208,18 +1209,18 @@ public:
};
class ImplicitParamDecl : public VarDecl {
- virtual void anchor();
+ void anchor() override;
public:
static ImplicitParamDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T);
static ImplicitParamDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- ImplicitParamDecl(DeclContext *DC, SourceLocation IdLoc,
+
+ ImplicitParamDecl(ASTContext &C, DeclContext *DC, SourceLocation IdLoc,
IdentifierInfo *Id, QualType Type)
- : VarDecl(ImplicitParam, DC, IdLoc, IdLoc, Id, Type,
- /*tinfo*/ 0, SC_None) {
+ : VarDecl(ImplicitParam, C, DC, IdLoc, IdLoc, Id, Type,
+ /*tinfo*/ nullptr, SC_None) {
setImplicit();
}
@@ -1235,11 +1236,10 @@ public:
enum { MaxFunctionScopeIndex = 255 };
protected:
- ParmVarDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, Expr *DefArg)
- : VarDecl(DK, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
+ ParmVarDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
+ : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) {
assert(ParmVarDeclBits.HasInheritedDefaultArg == false);
assert(ParmVarDeclBits.IsKNRPromoted == false);
assert(ParmVarDeclBits.IsObjCMethodParam == false);
@@ -1254,8 +1254,8 @@ public:
StorageClass S, Expr *DefArg);
static ParmVarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
void setObjCMethodScopeInfo(unsigned parameterIndex) {
ParmVarDeclBits.IsObjCMethodParam = true;
@@ -1362,9 +1362,7 @@ public:
/// real default argument via setDefaultArg when the class
/// definition enclosing the function declaration that owns this
/// default argument is completed.
- void setUnparsedDefaultArg() {
- Init = (UnparsedDefaultArgument *)0;
- }
+ void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; }
bool hasInheritedDefaultArg() const {
return ParmVarDeclBits.HasInheritedDefaultArg;
@@ -1538,7 +1536,7 @@ private:
void setParams(ASTContext &C, ArrayRef<ParmVarDecl *> NewParamInfo);
protected:
- FunctionDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
+ FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, bool isInlineSpecified,
@@ -1546,7 +1544,8 @@ protected:
: DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo,
StartLoc),
DeclContext(DK),
- ParamInfo(0), Body(),
+ redeclarable_base(C),
+ ParamInfo(nullptr), Body(),
SClass(S),
IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified),
IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false),
@@ -1559,18 +1558,22 @@ protected:
DNLoc(NameInfo.getInfo()) {}
typedef Redeclarable<FunctionDecl> redeclarable_base;
- virtual FunctionDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual FunctionDecl *getPreviousDeclImpl() {
+ FunctionDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
+ FunctionDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual FunctionDecl *getMostRecentDeclImpl() {
+ FunctionDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -1605,13 +1608,12 @@ public:
return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc);
}
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
void setRangeEnd(SourceLocation E) { EndRangeLoc = E; }
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Returns true if the function has a body (definition). The
/// function body might be in any of the (re-)declarations of this
@@ -1620,7 +1622,7 @@ public:
/// containing the body (if there is one).
bool hasBody(const FunctionDecl *&Definition) const;
- virtual bool hasBody() const {
+ bool hasBody() const override {
const FunctionDecl* Definition;
return hasBody(Definition);
}
@@ -1648,7 +1650,7 @@ public:
/// unnecessary AST de-serialization of the body.
Stmt *getBody(const FunctionDecl *&Definition) const;
- virtual Stmt *getBody() const {
+ Stmt *getBody() const override {
const FunctionDecl* Definition;
return getBody(Definition);
}
@@ -1828,7 +1830,7 @@ public:
void setPreviousDeclaration(FunctionDecl * PrevDecl);
virtual const FunctionDecl *getCanonicalDecl() const;
- virtual FunctionDecl *getCanonicalDecl();
+ FunctionDecl *getCanonicalDecl() override;
unsigned getBuiltinID() const;
@@ -1836,12 +1838,24 @@ public:
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() { return ParamInfo+param_size(); }
+ param_iterator param_begin() { return param_iterator(ParamInfo); }
+ param_iterator param_end() {
+ return param_iterator(ParamInfo + param_size());
+ }
+ param_range params() { return param_range(param_begin(), param_end()); }
- param_const_iterator param_begin() const { return ParamInfo; }
- param_const_iterator param_end() const { return ParamInfo+param_size(); }
+ param_const_iterator param_begin() const {
+ return param_const_iterator(ParamInfo);
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(ParamInfo + param_size());
+ }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
/// getNumParams - Return the number of parameters this function must have
/// based on its FunctionType. This is the length of the ParamInfo array
@@ -1860,6 +1874,12 @@ public:
setParams(getASTContext(), NewParamInfo);
}
+ // ArrayRef iterface to parameters.
+ // FIXME: Should one day replace iterator interface.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(ParamInfo, getNumParams());
+ }
+
const ArrayRef<NamedDecl *> &getDeclsInPrototypeScope() const {
return DeclsInPrototypeScope;
}
@@ -1871,10 +1891,15 @@ public:
/// arguments (in C++).
unsigned getMinRequiredArguments() const;
- QualType getResultType() const {
- return getType()->getAs<FunctionType>()->getResultType();
+ QualType getReturnType() const {
+ return getType()->getAs<FunctionType>()->getReturnType();
}
+ /// \brief Attempt to compute an informative source range covering the
+ /// function return type. This may omit qualifiers and other information with
+ /// limited representation in the AST.
+ SourceRange getReturnTypeSourceRange() const;
+
/// \brief Determine the type of an expression that calls this function.
QualType getCallResultType() const {
return getType()->getAs<FunctionType>()->getCallResultType(getASTContext());
@@ -1906,6 +1931,8 @@ public:
bool isInlineDefinitionExternallyVisible() const;
+ bool isMSExternInline() const;
+
bool doesDeclarationForceExternallyVisibleDefinition() const;
/// isOverloadedOperator - Whether this function declaration
@@ -1981,7 +2008,7 @@ public:
/// \brief Determine whether this function is a function template
/// specialization.
bool isFunctionTemplateSpecialization() const {
- return getPrimaryTemplate() != 0;
+ return getPrimaryTemplate() != nullptr;
}
/// \brief Retrieve the class scope template pattern that this function
@@ -2054,11 +2081,11 @@ public:
/// \param PointOfInstantiation point at which the function template
/// specialization was first instantiated.
void setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
- const TemplateArgumentListInfo *TemplateArgsAsWritten = 0,
- SourceLocation PointOfInstantiation = SourceLocation()) {
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos,
+ TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
+ const TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
+ SourceLocation PointOfInstantiation = SourceLocation()) {
setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
InsertPos, TSK, TemplateArgsAsWritten,
PointOfInstantiation);
@@ -2095,7 +2122,7 @@ public:
/// \brief Determine whether this is or was instantiated from an out-of-line
/// definition of a member function.
- virtual bool isOutOfLine() const;
+ bool isOutOfLine() const override;
/// \brief Identify a memory copying or setting function.
/// If the given function is a memory copy or setting function, returns
@@ -2181,7 +2208,7 @@ public:
bool isAnonymousStructOrUnion() const;
Expr *getBitWidth() const {
- return isBitField() ? InitializerOrBitWidth.getPointer() : 0;
+ return isBitField() ? InitializerOrBitWidth.getPointer() : nullptr;
}
unsigned getBitWidthValue(const ASTContext &Ctx) const;
@@ -2192,7 +2219,7 @@ public:
// Note: used by some clients (i.e., do not remove it).
void removeBitWidth() {
assert(isBitField() && "no bitfield width to remove");
- InitializerOrBitWidth.setPointer(0);
+ InitializerOrBitWidth.setPointer(nullptr);
}
/// getInClassInitStyle - Get the kind of (C++11) in-class initializer which
@@ -2211,7 +2238,8 @@ public:
/// in-class initializer, but this returns null, then we have not parsed and
/// attached it yet.
Expr *getInClassInitializer() const {
- return hasInClassInitializer() ? InitializerOrBitWidth.getPointer() : 0;
+ return hasInClassInitializer() ? InitializerOrBitWidth.getPointer()
+ : nullptr;
}
/// setInClassInitializer - Set the C++11 in-class initializer for this
/// member.
@@ -2220,7 +2248,7 @@ public:
/// member.
void removeInClassInitializer() {
assert(hasInClassInitializer() && "no initializer to remove");
- InitializerOrBitWidth.setPointer(0);
+ InitializerOrBitWidth.setPointer(nullptr);
InitializerOrBitWidth.setInt(ICIS_NoInit);
}
@@ -2234,10 +2262,10 @@ public:
return cast<RecordDecl>(getDeclContext());
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// Retrieves the canonical declaration of this field.
- FieldDecl *getCanonicalDecl() { return getFirstDecl(); }
+ FieldDecl *getCanonicalDecl() override { return getFirstDecl(); }
const FieldDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2276,10 +2304,10 @@ public:
void setInitExpr(Expr *E) { Init = (Stmt*) E; }
void setInitVal(const llvm::APSInt &V) { Val = V; }
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// Retrieves the canonical declaration of this enumerator.
- EnumConstantDecl *getCanonicalDecl() { return getFirstDecl(); }
+ EnumConstantDecl *getCanonicalDecl() override { return getFirstDecl(); }
const EnumConstantDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2293,7 +2321,7 @@ public:
/// field injected from an anonymous union/struct into the parent scope.
/// IndirectFieldDecl are always implicit.
class IndirectFieldDecl : public ValueDecl {
- virtual void anchor();
+ void anchor() override;
NamedDecl **Chaining;
unsigned ChainingSize;
@@ -2310,8 +2338,13 @@ public:
static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID);
typedef NamedDecl * const *chain_iterator;
- chain_iterator chain_begin() const { return Chaining; }
- chain_iterator chain_end() const { return Chaining+ChainingSize; }
+ typedef llvm::iterator_range<chain_iterator> chain_range;
+
+ chain_range chain() const { return chain_range(chain_begin(), chain_end()); }
+ chain_iterator chain_begin() const { return chain_iterator(Chaining); }
+ chain_iterator chain_end() const {
+ return chain_iterator(Chaining + ChainingSize);
+ }
unsigned getChainingSize() const { return ChainingSize; }
@@ -2334,7 +2367,7 @@ public:
/// TypeDecl - Represents a declaration of a type.
///
class TypeDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// TypeForDecl - This indicates the Type object that represents
/// this TypeDecl. It is a cache maintained by
/// ASTContext::getTypedefType, ASTContext::getTagDeclType, and
@@ -2343,16 +2376,11 @@ class TypeDecl : public NamedDecl {
/// LocStart - The start of the source range for this declaration.
SourceLocation LocStart;
friend class ASTContext;
- friend class DeclContext;
- friend class TagDecl;
- friend class TemplateTypeParmDecl;
- friend class TagType;
- friend class ASTReader;
protected:
TypeDecl(Kind DK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
SourceLocation StartL = SourceLocation())
- : NamedDecl(DK, DC, L, Id), TypeForDecl(0), LocStart(StartL) {}
+ : NamedDecl(DK, DC, L, Id), TypeForDecl(nullptr), LocStart(StartL) {}
public:
// Low-level accessor. If you just want the type defined by this node,
@@ -2364,7 +2392,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (LocStart.isValid())
return SourceRange(LocStart, getLocation());
else
@@ -2379,31 +2407,34 @@ public:
/// Base class for declarations which introduce a typedef-name.
class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
- virtual void anchor();
+ void anchor() override;
typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
protected:
- TypedefNameDecl(Kind DK, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- TypeSourceInfo *TInfo)
- : TypeDecl(DK, DC, IdLoc, Id, StartLoc), MaybeModedTInfo(TInfo) {}
+ TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
+ MaybeModedTInfo(TInfo) {}
typedef Redeclarable<TypedefNameDecl> redeclarable_base;
- virtual TypedefNameDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ TypedefNameDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual TypedefNameDecl *getPreviousDeclImpl() {
+ TypedefNameDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual TypedefNameDecl *getMostRecentDeclImpl() {
+ TypedefNameDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -2428,7 +2459,7 @@ public:
}
/// Retrieves the canonical declaration of this typedef-name.
- TypedefNameDecl *getCanonicalDecl() { return getFirstDecl(); }
+ TypedefNameDecl *getCanonicalDecl() override { return getFirstDecl(); }
const TypedefNameDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Implement isa/cast/dyncast/etc.
@@ -2441,17 +2472,17 @@ public:
/// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
/// type specifier.
class TypedefDecl : public TypedefNameDecl {
- TypedefDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(Typedef, DC, StartLoc, IdLoc, Id, TInfo) {}
+ TypedefDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(Typedef, C, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypedefDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypedefDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2461,9 +2492,9 @@ public:
/// TypeAliasDecl - Represents the declaration of a typedef-name via a C++0x
/// alias-declaration.
class TypeAliasDecl : public TypedefNameDecl {
- TypeAliasDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, TypeSourceInfo *TInfo)
- : TypedefNameDecl(TypeAlias, DC, StartLoc, IdLoc, Id, TInfo) {}
+ TypeAliasDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, TypeSourceInfo *TInfo)
+ : TypedefNameDecl(TypeAlias, C, DC, StartLoc, IdLoc, Id, TInfo) {}
public:
static TypeAliasDecl *Create(ASTContext &C, DeclContext *DC,
@@ -2471,7 +2502,7 @@ public:
IdentifierInfo *Id, TypeSourceInfo *TInfo);
static TypeAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2559,24 +2590,27 @@ private:
}
protected:
- TagDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, TagDecl *PrevDecl, SourceLocation StartL)
- : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), TagDeclKind(TK),
- IsCompleteDefinition(false), IsBeingDefined(false),
+ TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
+ SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl,
+ SourceLocation StartL)
+ : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C),
+ TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false),
IsEmbeddedInDeclarator(false), IsFreeStanding(false),
IsCompleteDefinitionRequired(false),
- NamedDeclOrQualifier((NamedDecl *)0) {
+ NamedDeclOrQualifier((NamedDecl *)nullptr) {
assert((DK != Enum || TK == TTK_Enum) &&
"EnumDecl not matched with TTK_Enum");
setPreviousDecl(PrevDecl);
}
typedef Redeclarable<TagDecl> redeclarable_base;
- virtual TagDecl *getNextRedeclaration() { return RedeclLink.getNext(); }
- virtual TagDecl *getPreviousDeclImpl() {
+ TagDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
+ }
+ TagDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual TagDecl *getMostRecentDeclImpl() {
+ TagDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2586,9 +2620,11 @@ protected:
void completeDefinition();
public:
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -2603,10 +2639,10 @@ public:
/// getOuterLocStart - Return SourceLocation representing start of source
/// range taking into account any outer template declarations.
SourceLocation getOuterLocStart() const;
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
- virtual TagDecl* getCanonicalDecl();
- const TagDecl* getCanonicalDecl() const {
+ TagDecl *getCanonicalDecl() override;
+ const TagDecl *getCanonicalDecl() const {
return const_cast<TagDecl*>(this)->getCanonicalDecl();
}
@@ -2673,8 +2709,7 @@ public:
IsCompleteDefinitionRequired = V;
}
- // FIXME: Return StringRef;
- const char *getKindName() const {
+ StringRef getKindName() const {
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
@@ -2714,12 +2749,12 @@ public:
NamedDeclOrQualifier.get<NamedDecl *>());
}
DeclaratorDecl *getDeclaratorForAnonDecl() const {
- return hasExtInfo() ? 0 : dyn_cast_or_null<DeclaratorDecl>(
+ return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>(
NamedDeclOrQualifier.get<NamedDecl *>());
}
TypedefNameDecl *getTypedefNameForAnonDecl() const {
- return hasExtInfo() ? 0 : dyn_cast_or_null<TypedefNameDecl>(
+ return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>(
NamedDeclOrQualifier.get<NamedDecl *>());
}
@@ -2731,7 +2766,7 @@ public:
/// declaration, if it was present in the source.
NestedNameSpecifier *getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : 0;
+ : nullptr;
}
/// \brief Retrieve the nested-name-specifier (with source-location
@@ -2773,7 +2808,7 @@ public:
/// with a fixed underlying type, and in C we allow them to be forward-declared
/// with no underlying type as an extension.
class EnumDecl : public TagDecl {
- virtual void anchor();
+ void anchor() override;
/// IntegerType - This represent the integer type that the enum corresponds
/// to for code generation purposes. Note that the enumerator constants may
/// have a different type than this does.
@@ -2802,13 +2837,13 @@ class EnumDecl : public TagDecl {
/// information.
MemberSpecializationInfo *SpecializationInfo;
- EnumDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, EnumDecl *PrevDecl,
+ EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl,
bool Scoped, bool ScopedUsingClassTag, bool Fixed)
- : TagDecl(Enum, TTK_Enum, DC, IdLoc, Id, PrevDecl, StartLoc),
- SpecializationInfo(0) {
+ : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc),
+ SpecializationInfo(nullptr) {
assert(Scoped || !ScopedUsingClassTag);
- IntegerType = (const Type*)0;
+ IntegerType = (const Type *)nullptr;
NumNegativeBits = 0;
NumPositiveBits = 0;
IsScoped = Scoped;
@@ -2819,7 +2854,7 @@ class EnumDecl : public TagDecl {
void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED,
TemplateSpecializationKind TSK);
public:
- EnumDecl *getCanonicalDecl() {
+ EnumDecl *getCanonicalDecl() override {
return cast<EnumDecl>(TagDecl::getCanonicalDecl());
}
const EnumDecl *getCanonicalDecl() const {
@@ -2865,6 +2900,12 @@ public:
// enumerator_iterator - Iterates through the enumerators of this
// enumeration.
typedef specific_decl_iterator<EnumConstantDecl> enumerator_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<EnumConstantDecl>>
+ enumerator_range;
+
+ enumerator_range enumerators() const {
+ return enumerator_range(enumerator_begin(), enumerator_end());
+ }
enumerator_iterator enumerator_begin() const {
const EnumDecl *E = getDefinition();
@@ -2888,27 +2929,32 @@ public:
void setPromotionType(QualType T) { PromotionType = T; }
/// getIntegerType - Return the integer type this enum decl corresponds to.
- /// This returns a null qualtype for an enum forward definition.
+ /// This returns a null QualType for an enum forward definition with no fixed
+ /// underlying type.
QualType getIntegerType() const {
if (!IntegerType)
return QualType();
- if (const Type* T = IntegerType.dyn_cast<const Type*>())
+ if (const Type *T = IntegerType.dyn_cast<const Type*>())
return QualType(T, 0);
- return IntegerType.get<TypeSourceInfo*>()->getType();
+ return IntegerType.get<TypeSourceInfo*>()->getType().getUnqualifiedType();
}
/// \brief Set the underlying integer type.
void setIntegerType(QualType T) { IntegerType = T.getTypePtrOrNull(); }
/// \brief Set the underlying integer type source info.
- void setIntegerTypeSourceInfo(TypeSourceInfo* TInfo) { IntegerType = TInfo; }
+ void setIntegerTypeSourceInfo(TypeSourceInfo *TInfo) { IntegerType = TInfo; }
/// \brief Return the type source info for the underlying integer type,
/// if no type source info exists, return 0.
- TypeSourceInfo* getIntegerTypeSourceInfo() const {
+ TypeSourceInfo *getIntegerTypeSourceInfo() const {
return IntegerType.dyn_cast<TypeSourceInfo*>();
}
+ /// \brief Retrieve the source range that covers the underlying type if
+ /// specified.
+ SourceRange getIntegerTypeRange() const LLVM_READONLY;
+
/// \brief Returns the width in bits required to store all the
/// non-negative enumerators of this enum.
unsigned getNumPositiveBits() const {
@@ -3024,14 +3070,14 @@ class RecordDecl : public TagDecl {
friend class DeclContext;
protected:
- RecordDecl(Kind DK, TagKind TK, DeclContext *DC,
+ RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl *PrevDecl);
public:
static RecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, RecordDecl* PrevDecl = 0);
+ IdentifierInfo *Id, RecordDecl* PrevDecl = nullptr);
static RecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
RecordDecl *getPreviousDecl() {
@@ -3106,7 +3152,9 @@ public:
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
typedef specific_decl_iterator<FieldDecl> field_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<FieldDecl>> field_range;
+ field_range fields() const { return field_range(field_begin(), field_end()); }
field_iterator field_begin() const;
field_iterator field_end() const {
@@ -3155,7 +3203,7 @@ public:
SourceLocation getAsmLoc() const { return getLocation(); }
SourceLocation getRParenLoc() const { return RParenLoc; }
void setRParenLoc(SourceLocation L) { RParenLoc = L; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getAsmLoc(), getRParenLoc());
}
@@ -3206,7 +3254,7 @@ public:
/// is not from outside the immediately enclosing function/block.
bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; }
- bool hasCopyExpr() const { return CopyExpr != 0; }
+ bool hasCopyExpr() const { return CopyExpr != nullptr; }
Expr *getCopyExpr() const { return CopyExpr; }
void setCopyExpr(Expr *e) { CopyExpr = e; }
};
@@ -3237,9 +3285,9 @@ protected:
: Decl(Block, DC, CaretLoc), DeclContext(Block),
IsVariadic(false), CapturesCXXThis(false),
BlockMissingReturnType(true), IsConversionFromLambda(false),
- ParamInfo(0), NumParams(0), Body(0),
- SignatureAsWritten(0), Captures(0), NumCaptures(0),
- ManglingNumber(0), ManglingContextDecl(0) {}
+ ParamInfo(nullptr), NumParams(0), Body(nullptr),
+ SignatureAsWritten(nullptr), Captures(nullptr), NumCaptures(0),
+ ManglingNumber(0), ManglingContextDecl(nullptr) {}
public:
static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
@@ -3251,7 +3299,7 @@ public:
void setIsVariadic(bool value) { IsVariadic = value; }
CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; }
- Stmt *getBody() const { return (Stmt*) Body; }
+ Stmt *getBody() const override { return (Stmt*) Body; }
void setBody(CompoundStmt *B) { Body = (Stmt*) B; }
void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; }
@@ -3261,13 +3309,31 @@ public:
unsigned param_size() const { return getNumParams(); }
typedef ParmVarDecl **param_iterator;
typedef ParmVarDecl * const *param_const_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+ // ArrayRef access to formal parameters.
+ // FIXME: Should eventual replace iterator access.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(ParamInfo, param_size());
+ }
bool param_empty() const { return NumParams == 0; }
- param_iterator param_begin() { return ParamInfo; }
- param_iterator param_end() { return ParamInfo+param_size(); }
+ param_range params() { return param_range(param_begin(), param_end()); }
+ param_iterator param_begin() { return param_iterator(ParamInfo); }
+ param_iterator param_end() {
+ return param_iterator(ParamInfo + param_size());
+ }
- param_const_iterator param_begin() const { return ParamInfo; }
- param_const_iterator param_end() const { return ParamInfo+param_size(); }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
+ param_const_iterator param_begin() const {
+ return param_const_iterator(ParamInfo);
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(ParamInfo + param_size());
+ }
unsigned getNumParams() const { return NumParams; }
const ParmVarDecl *getParamDecl(unsigned i) const {
@@ -3290,6 +3356,16 @@ public:
typedef const Capture *capture_iterator;
typedef const Capture *capture_const_iterator;
+ typedef llvm::iterator_range<capture_iterator> capture_range;
+ typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+ capture_range captures() {
+ return capture_range(capture_begin(), capture_end());
+ }
+ capture_const_range captures() const {
+ return capture_const_range(capture_begin(), capture_end());
+ }
+
capture_iterator capture_begin() { return Captures; }
capture_iterator capture_end() { return Captures + NumCaptures; }
capture_const_iterator capture_begin() const { return Captures; }
@@ -3321,7 +3397,7 @@ public:
ManglingContextDecl = Ctx;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -3340,12 +3416,14 @@ class CapturedDecl : public Decl, public DeclContext {
private:
/// \brief The number of parameters to the outlined function.
unsigned NumParams;
+ /// \brief The position of context parameter in list of parameters.
+ unsigned ContextParam;
/// \brief The body of the outlined function.
- Stmt *Body;
+ llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow;
explicit CapturedDecl(DeclContext *DC, unsigned NumParams)
: Decl(Captured, DC, SourceLocation()), DeclContext(Captured),
- NumParams(NumParams), Body(0) { }
+ NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { }
ImplicitParamDecl **getParams() const {
return reinterpret_cast<ImplicitParamDecl **>(
@@ -3353,12 +3431,16 @@ private:
}
public:
- static CapturedDecl *Create(ASTContext &C, DeclContext *DC, unsigned NumParams);
+ static CapturedDecl *Create(ASTContext &C, DeclContext *DC,
+ unsigned NumParams);
static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID,
unsigned NumParams);
- Stmt *getBody() const { return Body; }
- void setBody(Stmt *B) { Body = B; }
+ Stmt *getBody() const override { return BodyAndNothrow.getPointer(); }
+ void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); }
+
+ bool isNothrow() const { return BodyAndNothrow.getInt(); }
+ void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); }
unsigned getNumParams() const { return NumParams; }
@@ -3372,15 +3454,28 @@ public:
}
/// \brief Retrieve the parameter containing captured variables.
- ImplicitParamDecl *getContextParam() const { return getParam(0); }
- void setContextParam(ImplicitParamDecl *P) { setParam(0, P); }
+ ImplicitParamDecl *getContextParam() const {
+ assert(ContextParam < NumParams);
+ return getParam(ContextParam);
+ }
+ void setContextParam(unsigned i, ImplicitParamDecl *P) {
+ assert(i < NumParams);
+ ContextParam = i;
+ setParam(i, P);
+ }
+ unsigned getContextParamPosition() const { return ContextParam; }
typedef ImplicitParamDecl **param_iterator;
+ typedef llvm::iterator_range<param_iterator> param_range;
+
/// \brief Retrieve an iterator pointing to the first parameter decl.
param_iterator param_begin() const { return getParams(); }
/// \brief Retrieve an iterator one past the last parameter decl.
param_iterator param_end() const { return getParams() + NumParams; }
+ /// \brief Retrieve an iterator range for the parameter declarations.
+ param_range params() const { return param_range(param_begin(), param_end()); }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Captured; }
@@ -3455,9 +3550,9 @@ public:
/// This will return an empty array if the locations of the individual
/// identifiers aren't available.
ArrayRef<SourceLocation> getIdentifierLocs() const;
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
-
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Import; }
};
@@ -3496,6 +3591,8 @@ template<typename decl_type>
void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// Note: This routine is implemented here because we need both NamedDecl
// and Redeclarable to be defined.
+ assert(RedeclLink.NextIsLatest() &&
+ "setPreviousDecl on a decl already in a redeclaration chain");
decl_type *First;
@@ -3505,7 +3602,7 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
First = PrevDecl->getFirstDecl();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
- decl_type *MostRecent = First->RedeclLink.getNext();
+ decl_type *MostRecent = First->getNextRedeclaration();
RedeclLink = PreviousDeclLink(cast<decl_type>(MostRecent));
// If the declaration was previously visible, a redeclaration of it remains
@@ -3519,7 +3616,8 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
}
// First one will point to this one as latest.
- First->RedeclLink = LatestDeclLink(static_cast<decl_type*>(this));
+ First->RedeclLink.setLatest(static_cast<decl_type*>(this));
+
assert(!isa<NamedDecl>(static_cast<decl_type*>(this)) ||
cast<NamedDecl>(static_cast<decl_type*>(this))->isLinkageValid());
}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 26eea64f9d34..607ca4ec27c6 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -16,9 +16,9 @@
#include "clang/AST/AttrIterator.h"
#include "clang/AST/DeclarationName.h"
-#include "clang/Basic/Linkage.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -32,6 +32,8 @@ class DeclarationName;
class DependentDiagnostic;
class EnumDecl;
class FunctionDecl;
+class FunctionType;
+enum Linkage : unsigned char;
class LinkageComputer;
class LinkageSpecDecl;
class Module;
@@ -52,20 +54,6 @@ class TranslationUnitDecl;
class UsingDirectiveDecl;
}
-namespace llvm {
-// DeclContext* is only 4-byte aligned on 32-bit systems.
-template<>
- class PointerLikeTypeTraits<clang::DeclContext*> {
- typedef clang::DeclContext* PT;
-public:
- static inline void *getAsVoidPointer(PT P) { return P; }
- static inline PT getFromVoidPointer(void *P) {
- return static_cast<PT>(P);
- }
- enum { NumLowBitsAvailable = 2 };
-};
-}
-
namespace clang {
/// \brief Captures the result of checking the availability of a
@@ -302,8 +290,24 @@ protected:
template<typename decl_type> friend class Redeclarable;
+ /// \brief Allocate memory for a deserialized declaration.
+ ///
+ /// This routine must be used to allocate memory for any declaration that is
+ /// deserialized from a module file.
+ ///
+ /// \param Size The size of the allocated object.
+ /// \param Ctx The context in which we will allocate memory.
+ /// \param ID The global ID of the deserialized declaration.
+ /// \param Extra The amount of extra space to allocate after the object.
+ void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
+ std::size_t Extra = 0);
+
+ /// \brief Allocate memory for a non-deserialized declaration.
+ void *operator new(std::size_t Size, const ASTContext &Ctx,
+ DeclContext *Parent, std::size_t Extra = 0);
+
private:
- void CheckAccessDeclContext() const;
+ bool AccessDeclContextSanity() const;
protected:
@@ -330,18 +334,6 @@ protected:
virtual ~Decl();
- /// \brief Allocate memory for a deserialized declaration.
- ///
- /// This routine must be used to allocate memory for any declaration that is
- /// deserialized from a module file.
- ///
- /// \param Context The context in which we will allocate memory.
- /// \param ID The global ID of the deserialized declaration.
- /// \param Size The size of the allocated object.
- static void *AllocateDeserializedDecl(const ASTContext &Context,
- unsigned ID,
- unsigned Size);
-
/// \brief Update a potentially out-of-date declaration.
void updateOutOfDate(IdentifierInfo &II) const;
@@ -405,19 +397,17 @@ public:
bool isInAnonymousNamespace() const;
+ bool isInStdNamespace() const;
+
ASTContext &getASTContext() const LLVM_READONLY;
void setAccess(AccessSpecifier AS) {
Access = AS;
-#ifndef NDEBUG
- CheckAccessDeclContext();
-#endif
+ assert(AccessDeclContextSanity());
}
AccessSpecifier getAccess() const {
-#ifndef NDEBUG
- CheckAccessDeclContext();
-#endif
+ assert(AccessDeclContextSanity());
return AccessSpecifier(Access);
}
@@ -445,14 +435,17 @@ public:
}
typedef AttrVec::const_iterator attr_iterator;
+ typedef llvm::iterator_range<attr_iterator> attr_range;
+
+ attr_range attrs() const {
+ return attr_range(attr_begin(), attr_end());
+ }
- // FIXME: Do not rely on iterators having comparable singular values.
- // Note that this should error out if they do not.
attr_iterator attr_begin() const {
- return hasAttrs() ? getAttrs().begin() : 0;
+ return hasAttrs() ? getAttrs().begin() : nullptr;
}
attr_iterator attr_end() const {
- return hasAttrs() ? getAttrs().end() : 0;
+ return hasAttrs() ? getAttrs().end() : nullptr;
}
template <typename T>
@@ -467,6 +460,12 @@ public:
}
template <typename T>
+ llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const {
+ return llvm::iterator_range<specific_attr_iterator<T>>(
+ specific_attr_begin<T>(), specific_attr_end<T>());
+ }
+
+ template <typename T>
specific_attr_iterator<T> specific_attr_begin() const {
return specific_attr_iterator<T>(attr_begin());
}
@@ -476,7 +475,7 @@ public:
}
template<typename T> T *getAttr() const {
- return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+ return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr;
}
template<typename T> bool hasAttr() const {
return hasAttrs() && hasSpecificAttr<T>(getAttrs());
@@ -573,14 +572,14 @@ public:
/// AR_Available, will be set to a (possibly empty) message
/// describing why the declaration has not been introduced, is
/// deprecated, or is unavailable.
- AvailabilityResult getAvailability(std::string *Message = 0) const;
+ AvailabilityResult getAvailability(std::string *Message = nullptr) const;
/// \brief Determine whether this declaration is marked 'deprecated'.
///
/// \param Message If non-NULL and the declaration is deprecated,
/// this will be set to the message describing why the declaration
/// was deprecated (which may be empty).
- bool isDeprecated(std::string *Message = 0) const {
+ bool isDeprecated(std::string *Message = nullptr) const {
return getAvailability(Message) == AR_Deprecated;
}
@@ -589,7 +588,7 @@ public:
/// \param Message If non-NULL and the declaration is unavailable,
/// this will be set to the message describing why the declaration
/// was made unavailable (which may be empty).
- bool isUnavailable(std::string *Message = 0) const {
+ bool isUnavailable(std::string *Message = nullptr) const {
return getAvailability(Message) == AR_Unavailable;
}
@@ -636,7 +635,7 @@ private:
public:
Module *getOwningModule() const {
if (!isFromASTFile())
- return 0;
+ return nullptr;
return getOwningModuleSlow();
}
@@ -691,7 +690,7 @@ public:
/// roughly global variables and functions, but also handles enums (which
/// could be defined inside or outside a function etc).
bool isDefinedOutsideFunctionOrMethod() const {
- return getParentFunctionOrMethod() == 0;
+ return getParentFunctionOrMethod() == nullptr;
}
/// \brief If this decl is defined inside a function/method/block it returns
@@ -716,16 +715,16 @@ protected:
///
/// Decl subclasses that can be redeclared should override this method so that
/// Decl::redecl_iterator can iterate over them.
- virtual Decl *getNextRedeclaration() { return this; }
+ virtual Decl *getNextRedeclarationImpl() { return this; }
/// \brief Implementation of getPreviousDecl(), to be overridden by any
/// subclass that has a redeclaration chain.
- virtual Decl *getPreviousDeclImpl() { return 0; }
-
+ virtual Decl *getPreviousDeclImpl() { return nullptr; }
+
/// \brief Implementation of getMostRecentDecl(), to be overridden by any
- /// subclass that has a redeclaration chain.
+ /// subclass that has a redeclaration chain.
virtual Decl *getMostRecentDeclImpl() { return this; }
-
+
public:
/// \brief Iterates through all the redeclarations of the same decl.
class redecl_iterator {
@@ -740,7 +739,7 @@ public:
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- redecl_iterator() : Current(0) { }
+ redecl_iterator() : Current(nullptr) { }
explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { }
reference operator*() const { return Current; }
@@ -749,9 +748,9 @@ public:
redecl_iterator& operator++() {
assert(Current && "Advancing while iterator has reached end");
// Get either previous decl or latest decl.
- Decl *Next = Current->getNextRedeclaration();
+ Decl *Next = Current->getNextRedeclarationImpl();
assert(Next && "Should return next redeclaration or itself, never null!");
- Current = (Next != Starter ? Next : 0);
+ Current = (Next != Starter) ? Next : nullptr;
return *this;
}
@@ -769,10 +768,16 @@ public:
}
};
- /// \brief Returns iterator for all the redeclarations of the same decl.
- /// It will iterate at least once (when this decl is the only one).
+ typedef llvm::iterator_range<redecl_iterator> redecl_range;
+
+ /// \brief Returns an iterator range for all the redeclarations of the same
+ /// decl. It will iterate at least once (when this decl is the only one).
+ redecl_range redecls() const {
+ return redecl_range(redecls_begin(), redecls_end());
+ }
+
redecl_iterator redecls_begin() const {
- return redecl_iterator(const_cast<Decl*>(this));
+ return redecl_iterator(const_cast<Decl *>(this));
}
redecl_iterator redecls_end() const { return redecl_iterator(); }
@@ -788,7 +793,7 @@ public:
/// \brief True if this is the first declaration in its redeclaration chain.
bool isFirstDecl() const {
- return getPreviousDecl() == 0;
+ return getPreviousDecl() == nullptr;
}
/// \brief Retrieve the most recent declaration that declares the same entity
@@ -804,13 +809,13 @@ public:
/// getBody - If this Decl represents a declaration for a body of code,
/// such as a function or method definition, this method returns the
/// top-level Stmt* of that body. Otherwise this method returns null.
- virtual Stmt* getBody() const { return 0; }
+ virtual Stmt* getBody() const { return nullptr; }
/// \brief Returns true if this \c Decl represents a declaration for a body of
/// code, such as a function or method definition.
/// Note that \c hasBody can also return true if any redeclaration of this
/// \c Decl represents a declaration for a body of code.
- virtual bool hasBody() const { return getBody() != 0; }
+ virtual bool hasBody() const { return getBody() != nullptr; }
/// getBodyRBrace - Gets the right brace of the body, if a body exists.
/// This works whether the body is a CompoundStmt or a CXXTryStmt.
@@ -836,7 +841,19 @@ public:
bool isTemplateDecl() const;
/// \brief Whether this declaration is a function or function template.
- bool isFunctionOrFunctionTemplate() const;
+ bool isFunctionOrFunctionTemplate() const {
+ return (DeclKind >= Decl::firstFunction &&
+ DeclKind <= Decl::lastFunction) ||
+ DeclKind == FunctionTemplate;
+ }
+
+ /// \brief Returns the function itself, or the templated function if this is a
+ /// function template.
+ FunctionDecl *getAsFunction() LLVM_READONLY;
+
+ const FunctionDecl *getAsFunction() const {
+ return const_cast<Decl *>(this)->getAsFunction();
+ }
/// \brief Changes the namespace of this declaration to reflect that it's
/// a function-local extern declaration.
@@ -938,11 +955,16 @@ public:
raw_ostream &Out, const PrintingPolicy &Policy,
unsigned Indentation = 0);
// Debuggers don't usually respect default arguments.
- LLVM_ATTRIBUTE_USED void dump() const;
+ void dump() const;
// Same as dump(), but forces color printing.
- LLVM_ATTRIBUTE_USED void dumpColor() const;
+ void dumpColor() const;
void dump(raw_ostream &Out) const;
+ /// \brief Looks through the Decl's underlying type to extract a FunctionType
+ /// when possible. Will return null if the type underlying the Decl does not
+ /// have a FunctionType.
+ const FunctionType *getFunctionType(bool BlocksToo = true) const;
+
private:
void setAttrsImpl(const AttrVec& Attrs, ASTContext &Ctx);
void setDeclContextsImpl(DeclContext *SemaDC, DeclContext *LexicalDC,
@@ -975,10 +997,10 @@ public:
SourceManager &sm, const char *Msg)
: TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {}
- virtual void print(raw_ostream &OS) const;
+ void print(raw_ostream &OS) const override;
};
-typedef llvm::MutableArrayRef<NamedDecl*> DeclContextLookupResult;
+typedef MutableArrayRef<NamedDecl *> DeclContextLookupResult;
typedef ArrayRef<NamedDecl *> DeclContextLookupConstResult;
@@ -1048,8 +1070,8 @@ protected:
DeclContext(Decl::Kind K)
: DeclKind(K), ExternalLexicalStorage(false),
ExternalVisibleStorage(false),
- NeedToReconcileExternalVisibleStorage(false), LookupPtr(0, false),
- FirstDecl(0), LastDecl(0) {}
+ NeedToReconcileExternalVisibleStorage(false), LookupPtr(nullptr, false),
+ FirstDecl(nullptr), LastDecl(nullptr) {}
public:
~DeclContext();
@@ -1136,6 +1158,8 @@ public:
return DeclKind == Decl::Namespace;
}
+ bool isStdNamespace() const;
+
bool isInlineNamespace() const;
/// \brief Determines whether this context is dependent on a
@@ -1256,7 +1280,7 @@ public:
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- decl_iterator() : Current(0) { }
+ decl_iterator() : Current(nullptr) { }
explicit decl_iterator(Decl *C) : Current(C) { }
reference operator*() const { return Current; }
@@ -1282,8 +1306,11 @@ public:
}
};
+ typedef llvm::iterator_range<decl_iterator> decl_range;
+
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
+ decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
decl_iterator decls_begin() const;
decl_iterator decls_end() const { return decl_iterator(); }
bool decls_empty() const;
@@ -1291,7 +1318,10 @@ public:
/// noload_decls_begin/end - Iterate over the declarations stored in this
/// context that are currently loaded; don't attempt to retrieve anything
/// from an external source.
- decl_iterator noload_decls_begin() const;
+ decl_range noload_decls() const {
+ return decl_range(noload_decls_begin(), noload_decls_end());
+ }
+ decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
decl_iterator noload_decls_end() const { return decl_iterator(); }
/// specific_decl_iterator - Iterates over a subrange of
@@ -1537,6 +1567,11 @@ public:
/// of looking up every possible name.
class all_lookups_iterator;
+ typedef llvm::iterator_range<all_lookups_iterator> lookups_range;
+
+ lookups_range lookups() const;
+ lookups_range noload_lookups() const;
+
/// \brief Iterators over all possible lookups within this context.
all_lookups_iterator lookups_begin() const;
all_lookups_iterator lookups_end() const;
@@ -1547,26 +1582,15 @@ public:
all_lookups_iterator noload_lookups_begin() const;
all_lookups_iterator noload_lookups_end() const;
- /// udir_iterator - Iterates through the using-directives stored
- /// within this context.
- typedef UsingDirectiveDecl * const * udir_iterator;
-
- typedef std::pair<udir_iterator, udir_iterator> udir_iterator_range;
+ typedef llvm::iterator_range<UsingDirectiveDecl * const *> udir_range;
- udir_iterator_range getUsingDirectives() const;
-
- udir_iterator using_directives_begin() const {
- return getUsingDirectives().first;
- }
-
- udir_iterator using_directives_end() const {
- return getUsingDirectives().second;
- }
+ udir_range using_directives() const;
// These are all defined in DependentDiagnostic.h.
class ddiag_iterator;
- inline ddiag_iterator ddiag_begin() const;
- inline ddiag_iterator ddiag_end() const;
+ typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range;
+
+ inline ddiag_range ddiags() const;
// Low-level accessors
@@ -1616,12 +1640,12 @@ public:
static bool classof(const Decl *D);
static bool classof(const DeclContext *D) { return true; }
- LLVM_ATTRIBUTE_USED void dumpDeclContext() const;
- LLVM_ATTRIBUTE_USED void dumpLookups() const;
- LLVM_ATTRIBUTE_USED void dumpLookups(llvm::raw_ostream &OS) const;
+ void dumpDeclContext() const;
+ void dumpLookups() const;
+ void dumpLookups(llvm::raw_ostream &OS) const;
private:
- void reconcileExternalVisibleStorage();
+ void reconcileExternalVisibleStorage() const;
void LoadLexicalDeclsFromExternalStorage() const;
/// @brief Makes a declaration visible within this context, but
@@ -1650,7 +1674,7 @@ inline bool Decl::isTemplateParameter() const {
// Specialization selected when ToTy is not a known subclass of DeclContext.
template <class ToTy,
- bool IsKnownSubtype = ::llvm::is_base_of< DeclContext, ToTy>::value>
+ bool IsKnownSubtype = ::std::is_base_of<DeclContext, ToTy>::value>
struct cast_convert_decl_context {
static const ToTy *doit(const DeclContext *Val) {
return static_cast<const ToTy*>(Decl::castFromDeclContext(Val));
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index dbc41320bd72..72fad7c28e49 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,13 +17,12 @@
#define LLVM_CLANG_AST_DECLCXX_H
#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/TypeLoc.h"
+#include "clang/AST/LambdaCapture.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -122,14 +121,14 @@ public:
/// \brief Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getAccessSpecifierLoc(), getColonLoc());
}
static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
DeclContext *DC, SourceLocation ASLoc,
SourceLocation ColonLoc) {
- return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+ return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}
static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -258,20 +257,31 @@ public:
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
-/// The inheritance model to use for member pointers of a given CXXRecordDecl.
-enum MSInheritanceModel {
- MSIM_Single,
- MSIM_SinglePolymorphic,
- MSIM_Multiple,
- MSIM_MultiplePolymorphic,
- MSIM_Virtual,
- MSIM_Unspecified
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+ llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+ LazyDefinitionDataPtr update() {
+ if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+ if (Canon->isCanonicalDecl())
+ Canon->getMostRecentDecl();
+ else
+ // Declaration isn't canonical any more;
+ // update it and perform path compression.
+ *this = Canon->getPreviousDecl()->DefinitionData.update();
+ }
+ return *this;
+ }
+
+public:
+ LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+ LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+ T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+ T *get() { return update().getNotUpdated(); }
};
/// \brief Represents a C++ struct/union/class.
-///
-/// FIXME: This class will disappear once we've properly taught RecordDecl
-/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
friend void TagDecl::startDefinition();
@@ -350,10 +360,15 @@ class CXXRecordDecl : public RecordDecl {
/// \brief True if this class (or any subobject) has mutable fields.
bool HasMutableFields : 1;
+ /// \brief True if this class (or any nested anonymous struct or union)
+ /// has variant members.
+ bool HasVariantMembers : 1;
+
/// \brief True if there no non-field members declared by the user.
bool HasOnlyCMembers : 1;
- /// \brief True if any field has an in-class initializer.
+ /// \brief True if any field has an in-class initializer, including those
+ /// within anonymous unions or structs.
bool HasInClassInitializer : 1;
/// \brief True if any field is of reference type, and does not have an
@@ -409,7 +424,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief True if this class has a constexpr default constructor.
///
/// This is true for either a user-declared constexpr default constructor
- /// or an implicitly declared constexpr default constructor..
+ /// or an implicitly declared constexpr default constructor.
bool HasConstexprDefaultConstructor : 1;
/// \brief True when this class contains at least one non-static data
@@ -447,6 +462,9 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Whether this class describes a C++ lambda.
bool IsLambda : 1;
+ /// \brief Whether we are currently parsing base specifiers.
+ bool IsParsingBaseSpecifiers : 1;
+
/// \brief The number of base class specifiers in Bases.
unsigned NumBases;
@@ -486,33 +504,39 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
if (!Bases.isOffset())
- return Bases.get(0);
+ return Bases.get(nullptr);
return getBasesSlowCase();
}
/// \brief Retrieve the set of virtual base classes.
CXXBaseSpecifier *getVBases() const {
if (!VBases.isOffset())
- return VBases.get(0);
+ return VBases.get(nullptr);
return getVBasesSlowCase();
}
private:
CXXBaseSpecifier *getBasesSlowCase() const;
CXXBaseSpecifier *getVBasesSlowCase() const;
- } *DefinitionData;
+ };
+
+ typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
+ DefinitionDataPtr;
+ friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
+
+ mutable DefinitionDataPtr DefinitionData;
/// \brief Describes a C++ closure type (generated by a lambda expression).
struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaExpr::Capture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
+ typedef LambdaCapture Capture;
+
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
bool Dependent, bool IsGeneric,
LambdaCaptureDefault CaptureDefault)
: DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
- {
+ ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
+ MethodTyInfo(Info) {
IsLambda = true;
}
@@ -557,23 +581,20 @@ class CXXRecordDecl : public RecordDecl {
};
- struct DefinitionData &data() {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
- }
-
- const struct DefinitionData &data() const {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
+ struct DefinitionData &data() const {
+ auto *DD = DefinitionData.get();
+ assert(DD && "queried property of class with no definition");
+ return *DD;
}
struct LambdaDefinitionData &getLambdaData() const {
- assert(DefinitionData && "queried property of lambda with no definition");
- assert(DefinitionData->IsLambda &&
- "queried lambda property of non-lambda class");
- return static_cast<LambdaDefinitionData &>(*DefinitionData);
+ // No update required: a merged definition cannot change any lambda
+ // properties.
+ auto *DD = DefinitionData.getNotUpdated();
+ assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
+ return static_cast<LambdaDefinitionData&>(*DD);
}
-
+
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
@@ -610,7 +631,7 @@ class CXXRecordDecl : public RecordDecl {
FriendDecl *getFirstFriend() const;
protected:
- CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+ CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
@@ -621,17 +642,7 @@ public:
/// \brief Iterator that traverses the base classes of a class.
typedef const CXXBaseSpecifier* base_class_const_iterator;
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_iterator>
- reverse_base_class_iterator;
-
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_const_iterator>
- reverse_base_class_const_iterator;
-
- virtual CXXRecordDecl *getCanonicalDecl() {
+ CXXRecordDecl *getCanonicalDecl() override {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
virtual const CXXRecordDecl *getCanonicalDecl() const {
@@ -656,19 +667,20 @@ public:
}
CXXRecordDecl *getDefinition() const {
- if (!DefinitionData) return 0;
- return data().Definition;
+ auto *DD = DefinitionData.get();
+ return DD ? DD->Definition : nullptr;
}
- bool hasDefinition() const { return DefinitionData != 0; }
+ bool hasDefinition() const { return DefinitionData.get(); }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
+ IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl = nullptr,
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
+ bool DependentLambda, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
@@ -676,52 +688,52 @@ public:
return data().Polymorphic || data().NumVBases != 0;
}
+ void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+
+ bool isParsingBaseSpecifiers() const {
+ return data().IsParsingBaseSpecifiers;
+ }
+
/// \brief Sets the base classes of this struct or class.
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// \brief Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
+ typedef llvm::iterator_range<base_class_iterator> base_class_range;
+ typedef llvm::iterator_range<base_class_const_iterator>
+ base_class_const_range;
+
+ base_class_range bases() {
+ return base_class_range(bases_begin(), bases_end());
+ }
+ base_class_const_range bases() const {
+ return base_class_const_range(bases_begin(), bases_end());
+ }
+
base_class_iterator bases_begin() { return data().getBases(); }
base_class_const_iterator bases_begin() const { return data().getBases(); }
base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
base_class_const_iterator bases_end() const {
return bases_begin() + data().NumBases;
}
- reverse_base_class_iterator bases_rbegin() {
- return reverse_base_class_iterator(bases_end());
- }
- reverse_base_class_const_iterator bases_rbegin() const {
- return reverse_base_class_const_iterator(bases_end());
- }
- reverse_base_class_iterator bases_rend() {
- return reverse_base_class_iterator(bases_begin());
- }
- reverse_base_class_const_iterator bases_rend() const {
- return reverse_base_class_const_iterator(bases_begin());
- }
/// \brief Retrieves the number of virtual base classes of this class.
unsigned getNumVBases() const { return data().NumVBases; }
+ base_class_range vbases() {
+ return base_class_range(vbases_begin(), vbases_end());
+ }
+ base_class_const_range vbases() const {
+ return base_class_const_range(vbases_begin(), vbases_end());
+ }
+
base_class_iterator vbases_begin() { return data().getVBases(); }
base_class_const_iterator vbases_begin() const { return data().getVBases(); }
base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
base_class_const_iterator vbases_end() const {
return vbases_begin() + data().NumVBases;
}
- reverse_base_class_iterator vbases_rbegin() {
- return reverse_base_class_iterator(vbases_end());
- }
- reverse_base_class_const_iterator vbases_rbegin() const {
- return reverse_base_class_const_iterator(vbases_end());
- }
- reverse_base_class_iterator vbases_rend() {
- return reverse_base_class_iterator(vbases_begin());
- }
- reverse_base_class_const_iterator vbases_rend() const {
- return reverse_base_class_const_iterator(vbases_begin());
- }
/// \brief Determine whether this class has any dependent base classes which
/// are not the current instantiation.
@@ -731,6 +743,12 @@ public:
/// all method members of the class, including non-instance methods,
/// special methods, etc.
typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
+ method_range;
+
+ method_range methods() const {
+ return method_range(method_begin(), method_end());
+ }
/// \brief Method begin iterator. Iterates in the order the methods
/// were declared.
@@ -744,6 +762,10 @@ public:
/// Iterator access to constructor members.
typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
+ ctor_range;
+
+ ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
ctor_iterator ctor_begin() const {
return ctor_iterator(decls_begin());
@@ -755,6 +777,9 @@ public:
/// An iterator over friend declarations. All of these are defined
/// in DeclFriend.h.
class friend_iterator;
+ typedef llvm::iterator_range<friend_iterator> friend_range;
+
+ friend_range friends() const;
friend_iterator friend_begin() const;
friend_iterator friend_end() const;
void pushFriendDecl(FriendDecl *FD);
@@ -984,7 +1009,11 @@ public:
}
/// \brief Determine whether this class describes a lambda function object.
- bool isLambda() const { return hasDefinition() && data().IsLambda; }
+ bool isLambda() const {
+ // An update record can't turn a non-lambda into a lambda.
+ auto *DD = DefinitionData.getNotUpdated();
+ return DD && DD->IsLambda;
+ }
/// \brief Determine whether this class describes a generic
/// lambda function object (i.e. function call operator is
@@ -1025,12 +1054,18 @@ public:
void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const;
- typedef const LambdaExpr::Capture* capture_const_iterator;
+ typedef const LambdaCapture *capture_const_iterator;
+ typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+ capture_const_range captures() const {
+ return capture_const_range(captures_begin(), captures_end());
+ }
capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : NULL;
+ return isLambda() ? getLambdaData().Captures : nullptr;
}
capture_const_iterator captures_end() const {
- return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
+ return isLambda() ? captures_begin() + getLambdaData().NumCaptures
+ : nullptr;
}
typedef UnresolvedSetIterator conversion_iterator;
@@ -1058,7 +1093,8 @@ public:
bool isAggregate() const { return data().Aggregate; }
/// \brief Whether this class has any in-class initializers
- /// for non-static data members.
+ /// for non-static data members (including those in anonymous unions or
+ /// structs).
bool hasInClassInitializer() const { return data().HasInClassInitializer; }
/// \brief Whether this class or any of its subobjects has any members of
@@ -1117,6 +1153,9 @@ public:
/// contains a mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
+ /// \brief Determine whether this class has any variant members.
+ bool hasVariantMembers() const { return data().HasVariantMembers; }
+
/// \brief Determine whether this class has a trivial default constructor
/// (C++11 [class.ctor]p5).
bool hasTrivialDefaultConstructor() const {
@@ -1144,7 +1183,7 @@ public:
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer());
+ (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
}
/// \brief Determine whether this class has a constexpr default constructor.
@@ -1546,7 +1585,7 @@ public:
void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
/// \brief Indicates that the definition of this class is now complete.
- virtual void completeDefinition();
+ void completeDefinition() override;
/// \brief Indicates that the definition of this class is now complete,
/// and provides a final overrider map to help determine
@@ -1599,7 +1638,25 @@ public:
}
/// \brief Returns the inheritance model used for this record.
- MSInheritanceModel getMSInheritanceModel() const;
+ MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+ /// \brief Calculate what the inheritance model would be for this class.
+ MSInheritanceAttr::Spelling calculateInheritanceModel() const;
+
+ /// In the Microsoft C++ ABI, use zero for the field offset of a null data
+ /// member pointer if we can guarantee that zero is not a valid field offset,
+ /// or if the member pointer has multiple fields. Polymorphic classes have a
+ /// vfptr at offset zero, so we can use zero for null. If there are multiple
+ /// fields, we can use zero even if it is a valid field offset because
+ /// null-ness testing will check the other fields.
+ bool nullFieldOffsetIsZero() const {
+ return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
+ getMSInheritanceModel()) ||
+ (hasDefinition() && isPolymorphic());
+ }
+
+ /// \brief Controls when vtordisps will be emitted if this record is used as a
+ /// virtual base.
+ MSVtorDispAttr::Mode getMSVtorDispMode() const;
/// \brief Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
@@ -1636,14 +1693,14 @@ public:
/// In the terminology of the C++ Standard, these are the (static and
/// non-static) member functions, whether virtual or not.
class CXXMethodDecl : public FunctionDecl {
- virtual void anchor();
+ void anchor() override;
protected:
- CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
+ CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInline,
bool isConstexpr, SourceLocation EndLocation)
- : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+ : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
SC, isInline, isConstexpr) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
@@ -1683,9 +1740,9 @@ public:
CXXMethodDecl *CD =
cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
- // Methods declared in interfaces are automatically (pure) virtual.
- if (CD->isVirtualAsWritten() ||
- (CD->getParent()->isInterface() && CD->isUserProvided()))
+ // Member function is virtual if it is marked explicitly so, or if it is
+ // declared in __interface -- then it is automatically pure virtual.
+ if (CD->isVirtualAsWritten() || CD->isPure())
return true;
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
@@ -1703,10 +1760,10 @@ public:
/// \brief Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
- CXXMethodDecl *getCanonicalDecl() {
+ CXXMethodDecl *getCanonicalDecl() override {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
- const CXXMethodDecl *getCanonicalDecl() const {
+ const CXXMethodDecl *getCanonicalDecl() const override {
return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
}
@@ -1921,7 +1978,7 @@ public:
/// In-class member initializers (also known as "non-static data member
/// initializations", NSDMIs) were introduced in C++11.
bool isInClassMemberInitializer() const {
- return isa<CXXDefaultInitExpr>(Init);
+ return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
}
/// \brief Determine whether this initializer is creating a delegating
@@ -1968,20 +2025,20 @@ public:
FieldDecl *getMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
- return 0;
+ return nullptr;
}
FieldDecl *getAnyMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>()->getAnonField();
- return 0;
+ return nullptr;
}
IndirectFieldDecl *getIndirectMember() const {
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>();
- return 0;
+ return nullptr;
}
SourceLocation getMemberLocation() const {
@@ -2066,7 +2123,7 @@ public:
/// };
/// \endcode
class CXXConstructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief Whether this constructor declaration has the \c explicit keyword
/// specified.
bool IsExplicitSpecified : 1;
@@ -2078,14 +2135,14 @@ class CXXConstructorDecl : public CXXMethodDecl {
unsigned NumCtorInitializers;
/// \}
- CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0),
+ IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -2115,6 +2172,14 @@ public:
/// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
+ typedef llvm::iterator_range<init_iterator> init_range;
+ typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+ init_range inits() { return init_range(init_begin(), init_end()); }
+ init_const_range inits() const {
+ return init_const_range(init_begin(), init_end());
+ }
+
/// \brief Retrieve an iterator to the first initializer.
init_iterator init_begin() { return CtorInitializers; }
/// \brief Retrieve an iterator to the first initializer.
@@ -2240,10 +2305,10 @@ public:
/// \brief Set the constructor that this inheriting constructor is based on.
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
- const CXXConstructorDecl *getCanonicalDecl() const {
+ const CXXConstructorDecl *getCanonicalDecl() const override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
- CXXConstructorDecl *getCanonicalDecl() {
+ CXXConstructorDecl *getCanonicalDecl() override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
@@ -2266,17 +2331,17 @@ public:
/// };
/// \endcode
class CXXDestructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
FunctionDecl *OperatorDelete;
- CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(0) {
+ OperatorDelete(nullptr) {
setImplicit(isImplicitlyDeclared);
}
@@ -2289,8 +2354,12 @@ public:
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
- const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *OD) {
+ cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+ }
+ const FunctionDecl *getOperatorDelete() const {
+ return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2311,18 +2380,18 @@ public:
/// };
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// Whether this conversion function declaration is marked
/// "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
- CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified,
bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
@@ -2351,7 +2420,7 @@ public:
/// \brief Returns the type that this conversion function is converting to.
QualType getConversionType() const {
- return getType()->getAs<FunctionType>()->getResultType();
+ return getType()->getAs<FunctionType>()->getReturnType();
}
/// \brief Determine whether this conversion function is a conversion from
@@ -2440,7 +2509,7 @@ public:
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(ExternLoc, getLocEnd());
}
@@ -2465,7 +2534,7 @@ public:
/// artificial names for all using-directives in order to store
/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c using keyword.
SourceLocation UsingLoc;
@@ -2546,8 +2615,8 @@ public:
NamedDecl *Nominated,
DeclContext *CommonAncestor);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(UsingLoc, getLocation());
}
@@ -2568,7 +2637,7 @@ public:
/// namespace Foo = Bar;
/// \endcode
class NamespaceAliasDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
@@ -2641,8 +2710,8 @@ public:
NamedDecl *Namespace);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2664,7 +2733,7 @@ public:
/// }
/// \endcode
class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- virtual void anchor();
+ void anchor() override;
/// The referenced declaration.
NamedDecl *Underlying;
@@ -2674,10 +2743,10 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
NamedDecl *UsingOrNextShadow;
friend class UsingDecl;
- UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
- NamedDecl *Target)
+ UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+ UsingDecl *Using, NamedDecl *Target)
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- Underlying(Target),
+ redeclarable_base(C), Underlying(Target),
UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
if (Target) {
setDeclName(Target->getDeclName());
@@ -2687,13 +2756,13 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
}
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- virtual UsingShadowDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ UsingShadowDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual UsingShadowDecl *getPreviousDeclImpl() {
+ UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual UsingShadowDecl *getMostRecentDeclImpl() {
+ UsingShadowDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2701,21 +2770,23 @@ public:
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target) {
- return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
- virtual UsingShadowDecl *getCanonicalDecl() {
+ UsingShadowDecl *getCanonicalDecl() override {
return getFirstDecl();
}
- virtual const UsingShadowDecl *getCanonicalDecl() const {
+ const UsingShadowDecl *getCanonicalDecl() const {
return getFirstDecl();
}
@@ -2754,7 +2825,7 @@ public:
/// using someNameSpace::someIdentifier;
/// \endcode
class UsingDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
@@ -2778,7 +2849,7 @@ class UsingDecl : public NamedDecl {
const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
}
public:
@@ -2823,7 +2894,7 @@ public:
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- shadow_iterator() : Current(0) { }
+ shadow_iterator() : Current(nullptr) { }
explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
reference operator*() const { return Current; }
@@ -2848,6 +2919,11 @@ public:
}
};
+ typedef llvm::iterator_range<shadow_iterator> shadow_range;
+
+ shadow_range shadows() const {
+ return shadow_range(shadow_begin(), shadow_end());
+ }
shadow_iterator shadow_begin() const {
return shadow_iterator(FirstUsingShadow.getPointer());
}
@@ -2870,7 +2946,7 @@ public:
static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2891,7 +2967,7 @@ public:
/// };
/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
@@ -2944,7 +3020,7 @@ public:
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -2965,7 +3041,7 @@ public:
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
class UnresolvedUsingTypenameDecl : public TypeDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
@@ -3043,7 +3119,7 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getRParenLoc());
}
@@ -3083,21 +3159,24 @@ public:
class MSPropertyDecl : public DeclaratorDecl {
IdentifierInfo *GetterId, *SetterId;
-public:
- MSPropertyDecl(DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- SourceLocation StartL, IdentifierInfo *Getter,
- IdentifierInfo *Setter):
- DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
- SetterId(Setter) {}
+ MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter)
+ : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
+ GetterId(Getter), SetterId(Setter) {}
+public:
+ static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName N, QualType T,
+ TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter);
static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
- bool hasGetter() const { return GetterId != NULL; }
+ bool hasGetter() const { return GetterId != nullptr; }
IdentifierInfo* getGetterId() const { return GetterId; }
- bool hasSetter() const { return SetterId != NULL; }
+ bool hasSetter() const { return SetterId != nullptr; }
IdentifierInfo* getSetterId() const { return SetterId; }
friend class ASTDeclReader;
diff --git a/include/clang/AST/DeclContextInternals.h b/include/clang/AST/DeclContextInternals.h
index 9c626c80aaee..9068c00a799c 100644
--- a/include/clang/AST/DeclContextInternals.h
+++ b/include/clang/AST/DeclContextInternals.h
@@ -46,10 +46,8 @@ struct StoredDeclsList {
public:
StoredDeclsList() {}
- StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
- if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec),
- RHS.hasExternalDecls());
+ StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
+ RHS.Data = (NamedDecl *)nullptr;
}
~StoredDeclsList() {
@@ -58,12 +56,11 @@ public:
delete Vector;
}
- StoredDeclsList &operator=(const StoredDeclsList &RHS) {
+ StoredDeclsList &operator=(StoredDeclsList &&RHS) {
if (DeclsTy *Vector = getAsVector())
delete Vector;
Data = RHS.Data;
- if (DeclsTy *RHSVec = RHS.getAsVector())
- Data = DeclsAndHasExternalTy(new DeclsTy(*RHSVec), hasExternalDecls());
+ RHS.Data = (NamedDecl *)nullptr;
return *this;
}
@@ -110,7 +107,7 @@ public:
if (NamedDecl *Singleton = getAsDecl()) {
assert(Singleton == D && "list is different singleton");
(void)Singleton;
- Data = (NamedDecl *)0;
+ Data = (NamedDecl *)nullptr;
return;
}
@@ -145,8 +142,8 @@ public:
/// represents.
DeclContext::lookup_result getLookupResult() {
if (isNull())
- return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
- DeclContext::lookup_iterator(0));
+ return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr),
+ DeclContext::lookup_iterator(nullptr));
// If we have a single NamedDecl, return it.
if (getAsDecl()) {
@@ -255,7 +252,7 @@ private:
class DependentStoredDeclsMap : public StoredDeclsMap {
public:
- DependentStoredDeclsMap() : FirstDiagnostic(0) {}
+ DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
private:
friend class DependentDiagnostic;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index be6f2eb3e3ad..12b93b408a70 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -17,6 +17,7 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/TypeLoc.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -91,7 +92,7 @@ private:
FriendDecl *getNextFriend() {
if (!NextFriend.isOffset())
- return cast_or_null<FriendDecl>(NextFriend.get(0));
+ return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
return getNextFriendSlowCase();
}
FriendDecl *getNextFriendSlowCase();
@@ -132,10 +133,14 @@ public:
}
/// Retrieves the source range for the friend declaration.
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (NamedDecl *ND = getFriendDecl()) {
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
+ return FD->getSourceRange();
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
return FTD->getSourceRange();
+ if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
+ return CTD->getSourceRange();
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
if (DD->getOuterLocStart() != DD->getInnerLocStart())
return DD->getSourceRange();
@@ -224,7 +229,11 @@ inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
}
inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
- return friend_iterator(0);
+ return friend_iterator(nullptr);
+}
+
+inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
+ return friend_range(friend_begin(), friend_end());
}
inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
diff --git a/include/clang/AST/DeclGroup.h b/include/clang/AST/DeclGroup.h
index cda6ae520af4..bd3dbd8fa787 100644
--- a/include/clang/AST/DeclGroup.h
+++ b/include/clang/AST/DeclGroup.h
@@ -63,7 +63,7 @@ class DeclGroupRef {
}
public:
- DeclGroupRef() : D(0) {}
+ DeclGroupRef() : D(nullptr) {}
explicit DeclGroupRef(Decl* d) : D(d) {}
explicit DeclGroupRef(DeclGroup* dg)
@@ -80,7 +80,7 @@ public:
typedef Decl** iterator;
typedef Decl* const * const_iterator;
- bool isNull() const { return D == 0; }
+ bool isNull() const { return D == nullptr; }
bool isSingleDecl() const { return getKind() == SingleDeclKind; }
bool isDeclGroup() const { return getKind() == DeclGroupKind; }
@@ -102,26 +102,26 @@ public:
iterator begin() {
if (isSingleDecl())
- return D ? &D : 0;
+ return D ? &D : nullptr;
return &getDeclGroup()[0];
}
iterator end() {
if (isSingleDecl())
- return D ? &D+1 : 0;
+ return D ? &D+1 : nullptr;
DeclGroup &G = getDeclGroup();
return &G[0] + G.size();
}
const_iterator begin() const {
if (isSingleDecl())
- return D ? &D : 0;
+ return D ? &D : nullptr;
return &getDeclGroup()[0];
}
const_iterator end() const {
if (isSingleDecl())
- return D ? &D+1 : 0;
+ return D ? &D+1 : nullptr;
const DeclGroup &G = getDeclGroup();
return &G[0] + G.size();
}
diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h
index c16975a3307f..d2016af89f13 100644
--- a/include/clang/AST/DeclLookups.h
+++ b/include/clang/AST/DeclLookups.h
@@ -68,38 +68,40 @@ public:
}
};
-inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+inline DeclContext::lookups_range DeclContext::lookups() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
if (Primary->hasExternalVisibleStorage())
getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
if (StoredDeclsMap *Map = Primary->buildLookup())
- return all_lookups_iterator(Map->begin(), Map->end());
- return all_lookups_iterator();
+ return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+ all_lookups_iterator(Map->end(), Map->end()));
+ return lookups_range();
+}
+
+inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
+ return lookups().begin();
}
inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
+ return lookups().end();
+}
+
+inline DeclContext::lookups_range DeclContext::noload_lookups() const {
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (Primary->hasExternalVisibleStorage())
- getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
- if (StoredDeclsMap *Map = Primary->buildLookup())
- return all_lookups_iterator(Map->end(), Map->end());
- return all_lookups_iterator();
+ if (StoredDeclsMap *Map = Primary->getLookupPtr())
+ return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
+ all_lookups_iterator(Map->end(), Map->end()));
+ return lookups_range();
}
inline
DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return all_lookups_iterator(Map->begin(), Map->end());
- return all_lookups_iterator();
+ return noload_lookups().begin();
}
inline
DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
- DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
- if (StoredDeclsMap *Map = Primary->getLookupPtr())
- return all_lookups_iterator(Map->end(), Map->end());
- return all_lookups_iterator();
+ return noload_lookups().end();
}
} // end namespace clang
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 2e760d658e43..db3b0849382a 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -41,7 +41,7 @@ protected:
unsigned NumElts;
public:
- ObjCListBase() : List(0), NumElts(0) {}
+ ObjCListBase() : List(nullptr), NumElts(0) {}
unsigned size() const { return NumElts; }
bool empty() const { return NumElts == 0; }
@@ -79,7 +79,7 @@ class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
using ObjCList<ObjCProtocolDecl>::set;
public:
- ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(0) { }
+ ObjCProtocolList() : ObjCList<ObjCProtocolDecl>(), Locations(nullptr) { }
typedef const SourceLocation *loc_iterator;
loc_iterator loc_begin() const { return Locations; }
@@ -162,11 +162,11 @@ private:
/// \brief Indicates if the method was a definition but its body was skipped.
unsigned HasSkippedBody : 1;
- // Result type of this method.
+ // Return type of this method.
QualType MethodDeclType;
- // Type source information for the result type.
- TypeSourceInfo *ResultTInfo;
+ // Type source information for the return type.
+ TypeSourceInfo *ReturnTInfo;
/// \brief Array of ParmVarDecls for the formal parameters of this method
/// and optionally followed by selector locations.
@@ -224,54 +224,44 @@ private:
ArrayRef<SourceLocation> SelLocs);
ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
- Selector SelInfo, QualType T,
- TypeSourceInfo *ResultTInfo,
- DeclContext *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false,
- bool isDefined = false,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance = true,
+ bool isVariadic = false, bool isPropertyAccessor = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
ImplementationControl impControl = None,
bool HasRelatedResultType = false)
- : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
- DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
- IsInstance(isInstance), IsVariadic(isVariadic),
- IsPropertyAccessor(isPropertyAccessor),
- IsDefined(isDefined), IsRedeclaration(0), HasRedeclaration(0),
- DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
- RelatedResultType(HasRelatedResultType),
- SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
- MethodDeclType(T), ResultTInfo(ResultTInfo),
- ParamsAndSelLocs(0), NumParams(0),
- DeclEndLoc(endLoc), Body(), SelfDecl(0), CmdDecl(0) {
+ : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
+ DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily),
+ IsInstance(isInstance), IsVariadic(isVariadic),
+ IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined),
+ IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl),
+ objcDeclQualifier(OBJC_TQ_None),
+ RelatedResultType(HasRelatedResultType),
+ SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0),
+ MethodDeclType(T), ReturnTInfo(ReturnTInfo), ParamsAndSelLocs(nullptr),
+ NumParams(0), DeclEndLoc(endLoc), Body(), SelfDecl(nullptr),
+ CmdDecl(nullptr) {
setImplicit(isImplicitlyDeclared);
}
/// \brief A definition will return its interface declaration.
/// An interface declaration will return its definition.
/// Otherwise it will return itself.
- virtual ObjCMethodDecl *getNextRedeclaration();
+ ObjCMethodDecl *getNextRedeclarationImpl() override;
public:
- static ObjCMethodDecl *Create(ASTContext &C,
- SourceLocation beginLoc,
- SourceLocation endLoc,
- Selector SelInfo,
- QualType T,
- TypeSourceInfo *ResultTInfo,
- DeclContext *contextDecl,
- bool isInstance = true,
- bool isVariadic = false,
- bool isPropertyAccessor = false,
- bool isImplicitlyDeclared = false,
- bool isDefined = false,
- ImplementationControl impControl = None,
- bool HasRelatedResultType = false);
+ static ObjCMethodDecl *
+ Create(ASTContext &C, SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, bool isInstance = true,
+ bool isVariadic = false, bool isPropertyAccessor = false,
+ bool isImplicitlyDeclared = false, bool isDefined = false,
+ ImplementationControl impControl = None,
+ bool HasRelatedResultType = false);
static ObjCMethodDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual ObjCMethodDecl *getCanonicalDecl();
+
+ ObjCMethodDecl *getCanonicalDecl() override;
const ObjCMethodDecl *getCanonicalDecl() const {
return const_cast<ObjCMethodDecl*>(this)->getCanonicalDecl();
}
@@ -300,7 +290,7 @@ public:
// Location information, modeled after the Stmt API.
SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); }
SourceLocation getLocEnd() const LLVM_READONLY;
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getLocEnd());
}
@@ -314,8 +304,7 @@ public:
if (hasStandardSelLocs())
return getStandardSelectorLoc(Index, getSelector(),
getSelLocsKind() == SelLoc_StandardWithSpace,
- llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
- NumParams),
+ parameters(),
DeclEndLoc);
return getStoredSelLocs()[Index];
}
@@ -338,32 +327,52 @@ public:
Selector getSelector() const { return getDeclName().getObjCSelector(); }
- QualType getResultType() const { return MethodDeclType; }
- void setResultType(QualType T) { MethodDeclType = T; }
+ QualType getReturnType() const { return MethodDeclType; }
+ void setReturnType(QualType T) { MethodDeclType = T; }
/// \brief Determine the type of an expression that sends a message to this
/// function.
QualType getSendResultType() const {
- return getResultType().getNonLValueExprType(getASTContext());
+ return getReturnType().getNonLValueExprType(getASTContext());
}
- TypeSourceInfo *getResultTypeSourceInfo() const { return ResultTInfo; }
- void setResultTypeSourceInfo(TypeSourceInfo *TInfo) { ResultTInfo = TInfo; }
+ TypeSourceInfo *getReturnTypeSourceInfo() const { return ReturnTInfo; }
+ void setReturnTypeSourceInfo(TypeSourceInfo *TInfo) { ReturnTInfo = TInfo; }
// Iterator access to formal parameters.
unsigned param_size() const { return NumParams; }
typedef const ParmVarDecl *const *param_const_iterator;
typedef ParmVarDecl *const *param_iterator;
- param_const_iterator param_begin() const { return getParams(); }
- param_const_iterator param_end() const { return getParams() + NumParams; }
- param_iterator param_begin() { return getParams(); }
- param_iterator param_end() { return getParams() + NumParams; }
+ typedef llvm::iterator_range<param_iterator> param_range;
+ typedef llvm::iterator_range<param_const_iterator> param_const_range;
+
+ param_range params() { return param_range(param_begin(), param_end()); }
+ param_const_range params() const {
+ return param_const_range(param_begin(), param_end());
+ }
+
+ param_const_iterator param_begin() const {
+ return param_const_iterator(getParams());
+ }
+ param_const_iterator param_end() const {
+ return param_const_iterator(getParams() + NumParams);
+ }
+ param_iterator param_begin() { return param_iterator(getParams()); }
+ param_iterator param_end() { return param_iterator(getParams() + NumParams); }
+
// This method returns and of the parameters which are part of the selector
// name mangling requirements.
param_const_iterator sel_param_end() const {
return param_begin() + getSelector().getNumArgs();
}
+ // ArrayRef access to formal parameters. This should eventually
+ // replace the iterator interface above.
+ ArrayRef<ParmVarDecl*> parameters() const {
+ return llvm::makeArrayRef(const_cast<ParmVarDecl**>(getParams()),
+ NumParams);
+ }
+
/// \brief Sets the method's parameters and selector source locations.
/// If the method is implicit (not coming from source) \p SelLocs is
/// ignored.
@@ -375,12 +384,12 @@ public:
// Iterator access to parameter types.
typedef std::const_mem_fun_t<QualType, ParmVarDecl> deref_fun;
typedef llvm::mapped_iterator<param_const_iterator, deref_fun>
- arg_type_iterator;
+ param_type_iterator;
- arg_type_iterator arg_type_begin() const {
+ param_type_iterator param_type_begin() const {
return llvm::map_iterator(param_begin(), deref_fun(&ParmVarDecl::getType));
}
- arg_type_iterator arg_type_end() const {
+ param_type_iterator param_type_end() const {
return llvm::map_iterator(param_end(), deref_fun(&ParmVarDecl::getType));
}
@@ -451,11 +460,24 @@ public:
return ImplementationControl(DeclImplementation);
}
+ /// Returns true if this specific method declaration is marked with the
+ /// designated initializer attribute.
+ bool isThisDeclarationADesignatedInitializer() const;
+
+ /// Returns true if the method selector resolves to a designated initializer
+ /// in the class's interface.
+ ///
+ /// \param InitMethod if non-null and the function returns true, it receives
+ /// the method declaration that was marked with the designated initializer
+ /// attribute.
+ bool isDesignatedInitializerForTheInterface(
+ const ObjCMethodDecl **InitMethod = nullptr) const;
+
/// \brief Determine whether this method has a body.
- virtual bool hasBody() const { return Body.isValid(); }
+ bool hasBody() const override { return Body.isValid(); }
/// \brief Retrieve the body of this method, if it has one.
- virtual Stmt *getBody() const;
+ Stmt *getBody() const override;
void setLazyBody(uint64_t Offset) { Body = Offset; }
@@ -484,7 +506,7 @@ public:
/// ObjCProtocolDecl, and ObjCImplDecl.
///
class ObjCContainerDecl : public NamedDecl, public DeclContext {
- virtual void anchor();
+ void anchor() override;
SourceLocation AtStart;
@@ -500,6 +522,10 @@ public:
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>>
+ prop_range;
+
+ prop_range properties() const { return prop_range(prop_begin(), prop_end()); }
prop_iterator prop_begin() const {
return prop_iterator(decls_begin());
}
@@ -509,6 +535,12 @@ public:
// Iterator access to instance/class methods.
typedef specific_decl_iterator<ObjCMethodDecl> method_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>>
+ method_range;
+
+ method_range methods() const {
+ return method_range(meth_begin(), meth_end());
+ }
method_iterator meth_begin() const {
return method_iterator(decls_begin());
}
@@ -519,6 +551,11 @@ public:
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isInstanceMethod>
instmeth_iterator;
+ typedef llvm::iterator_range<instmeth_iterator> instmeth_range;
+
+ instmeth_range instance_methods() const {
+ return instmeth_range(instmeth_begin(), instmeth_end());
+ }
instmeth_iterator instmeth_begin() const {
return instmeth_iterator(decls_begin());
}
@@ -529,6 +566,11 @@ public:
typedef filtered_decl_iterator<ObjCMethodDecl,
&ObjCMethodDecl::isClassMethod>
classmeth_iterator;
+ typedef llvm::iterator_range<classmeth_iterator> classmeth_range;
+
+ classmeth_range class_methods() const {
+ return classmeth_range(classmeth_begin(), classmeth_end());
+ }
classmeth_iterator classmeth_begin() const {
return classmeth_iterator(decls_begin());
}
@@ -575,7 +617,7 @@ public:
AtEnd = atEnd;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(AtStart, getAtEndRange().getEnd());
}
@@ -621,7 +663,7 @@ public:
///
class ObjCInterfaceDecl : public ObjCContainerDecl
, public Redeclarable<ObjCInterfaceDecl> {
- virtual void anchor();
+ void anchor() override;
/// TypeForDecl - This indicates the Type object that represents this
/// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType
@@ -661,6 +703,22 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
/// declared in the implementation.
mutable bool IvarListMissingImplementation : 1;
+ /// Indicates that this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ bool HasDesignatedInitializers : 1;
+
+ enum InheritedDesignatedInitializersState {
+ /// We didn't calculate whether the designated initializers should be
+ /// inherited or not.
+ IDI_Unknown = 0,
+ /// Designated initializers are inherited for the super class.
+ IDI_Inherited = 1,
+ /// The class does not inherit designated initializers.
+ IDI_NotInherited = 2
+ };
+ /// One of the \c InheritedDesignatedInitializersState enumeratos.
+ mutable unsigned InheritedDesignatedInitializers : 2;
+
/// \brief The location of the superclass, if any.
SourceLocation SuperClassLoc;
@@ -671,12 +729,14 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
ExternallyCompleted(),
- IvarListMissingImplementation(true) { }
+ IvarListMissingImplementation(true),
+ HasDesignatedInitializers(),
+ InheritedDesignatedInitializers(IDI_Unknown) { }
};
- ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
- SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
- bool isInternal);
+ ObjCInterfaceDecl(const ASTContext &C, DeclContext *DC, SourceLocation AtLoc,
+ IdentifierInfo *Id, SourceLocation CLoc,
+ ObjCInterfaceDecl *PrevDecl, bool IsInternal);
void LoadExternalDefinition() const;
@@ -696,13 +756,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
void allocateDefinitionData();
typedef Redeclarable<ObjCInterfaceDecl> redeclarable_base;
- virtual ObjCInterfaceDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ ObjCInterfaceDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual ObjCInterfaceDecl *getPreviousDeclImpl() {
+ ObjCInterfaceDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual ObjCInterfaceDecl *getMostRecentDeclImpl() {
+ ObjCInterfaceDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -714,9 +774,9 @@ public:
SourceLocation ClassLoc = SourceLocation(),
bool isInternal = false);
- static ObjCInterfaceDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ static ObjCInterfaceDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
@@ -728,6 +788,20 @@ public:
/// when a complete class is required.
void setExternallyCompleted();
+ /// Indicate that this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ void setHasDesignatedInitializers();
+
+ /// Returns true if this interface decl contains at least one initializer
+ /// marked with the 'objc_designated_initializer' attribute.
+ bool hasDesignatedInitializers() const;
+
+ /// Returns true if this interface decl declares a designated initializer
+ /// or it inherites one from its super class.
+ bool declaresOrInheritsDesignatedInitializers() const {
+ return hasDesignatedInitializers() || inheritsDesignatedInitializers();
+ }
+
const ObjCProtocolList &getReferencedProtocols() const {
assert(hasDefinition() && "Caller did not check for forward reference!");
if (data().ExternallyCompleted)
@@ -750,7 +824,11 @@ public:
}
typedef ObjCProtocolList::iterator protocol_iterator;
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
protocol_iterator protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -773,7 +851,11 @@ public:
}
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -797,7 +879,12 @@ public:
}
typedef ObjCList<ObjCProtocolDecl>::iterator all_protocol_iterator;
+ typedef llvm::iterator_range<all_protocol_iterator> all_protocol_range;
+ all_protocol_range all_referenced_protocols() const {
+ return all_protocol_range(all_referenced_protocol_begin(),
+ all_referenced_protocol_end());
+ }
all_protocol_iterator all_referenced_protocol_begin() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
@@ -824,7 +911,9 @@ public:
}
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
if (const ObjCInterfaceDecl *Def = getDefinition())
return ivar_iterator(Def->decls_begin());
@@ -867,6 +956,31 @@ public:
unsigned Num,
ASTContext &C);
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
+
+ /// Returns the designated initializers for the interface.
+ ///
+ /// If this declaration does not have methods marked as designated
+ /// initializers then the interface inherits the designated initializers of
+ /// its super class.
+ void getDesignatedInitializers(
+ llvm::SmallVectorImpl<const ObjCMethodDecl *> &Methods) const;
+
+ /// Returns true if the given selector is a designated initializer for the
+ /// interface.
+ ///
+ /// If this declaration does not have methods marked as designated
+ /// initializers then the interface inherits the designated initializers of
+ /// its super class.
+ ///
+ /// \param InitMethod if non-null and the function returns true, it receives
+ /// the method that was marked as a designated initializer.
+ bool
+ isDesignatedInitializer(Selector Sel,
+ const ObjCMethodDecl **InitMethod = nullptr) const;
+
/// \brief Determine whether this particular declaration of this class is
/// actually also a definition.
bool isThisDeclarationADefinition() const {
@@ -894,14 +1008,14 @@ public:
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
ObjCInterfaceDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Retrieve the definition of this class, or NULL if this class
/// has been forward-declared (with \@class) but not yet defined (with
/// \@interface).
const ObjCInterfaceDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Starts the definition of this Objective-C class, taking it from
@@ -911,7 +1025,7 @@ public:
ObjCInterfaceDecl *getSuperClass() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -943,7 +1057,7 @@ public:
typedef std::ptrdiff_t difference_type;
typedef std::input_iterator_tag iterator_category;
- filtered_category_iterator() : Current(0) { }
+ filtered_category_iterator() : Current(nullptr) { }
explicit filtered_category_iterator(ObjCCategoryDecl *Current)
: Current(Current)
{
@@ -984,6 +1098,14 @@ public:
typedef filtered_category_iterator<isVisibleCategory>
visible_categories_iterator;
+ typedef llvm::iterator_range<visible_categories_iterator>
+ visible_categories_range;
+
+ visible_categories_range visible_categories() const {
+ return visible_categories_range(visible_categories_begin(),
+ visible_categories_end());
+ }
+
/// \brief Retrieve an iterator to the beginning of the visible-categories
/// list.
visible_categories_iterator visible_categories_begin() const {
@@ -1010,6 +1132,13 @@ public:
/// \brief Iterator that walks over all of the known categories and
/// extensions, including those that are hidden.
typedef filtered_category_iterator<isKnownCategory> known_categories_iterator;
+ typedef llvm::iterator_range<known_categories_iterator>
+ known_categories_range;
+
+ known_categories_range known_categories() const {
+ return known_categories_range(known_categories_begin(),
+ known_categories_end());
+ }
/// \brief Retrieve an iterator to the beginning of the known-categories
/// list.
@@ -1039,6 +1168,14 @@ public:
typedef filtered_category_iterator<isVisibleExtension>
visible_extensions_iterator;
+ typedef llvm::iterator_range<visible_extensions_iterator>
+ visible_extensions_range;
+
+ visible_extensions_range visible_extensions() const {
+ return visible_extensions_range(visible_extensions_begin(),
+ visible_extensions_end());
+ }
+
/// \brief Retrieve an iterator to the beginning of the visible-extensions
/// list.
visible_extensions_iterator visible_extensions_begin() const {
@@ -1065,6 +1202,13 @@ public:
/// \brief Iterator that walks over all of the known extensions.
typedef filtered_category_iterator<isKnownExtension>
known_extensions_iterator;
+ typedef llvm::iterator_range<known_extensions_iterator>
+ known_extensions_range;
+
+ known_extensions_range known_extensions() const {
+ return known_extensions_range(known_extensions_begin(),
+ known_extensions_end());
+ }
/// \brief Retrieve an iterator to the beginning of the known-extensions
/// list.
@@ -1087,7 +1231,7 @@ public:
ObjCCategoryDecl* getCategoryListRaw() const {
// FIXME: Should make sure no callers ever do this.
if (!hasDefinition())
- return 0;
+ return nullptr;
if (data().ExternallyCompleted)
LoadExternalDefinition();
@@ -1104,14 +1248,14 @@ public:
ObjCPropertyDecl
*FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const;
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const;
+ void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const override;
/// isSuperClassOf - Return true if this class is the specified class or is a
/// super class of the specified interface class.
bool isSuperClassOf(const ObjCInterfaceDecl *I) const {
// If RHS is derived from LHS it is OK; else it is not OK.
- while (I != NULL) {
+ while (I != nullptr) {
if (declaresSameEntity(this, I))
return true;
@@ -1141,15 +1285,18 @@ public:
// Lookup a method. First, we search locally. If a method isn't
// found, we search referenced protocols and class categories.
ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance,
- bool shallowCategoryLookup= false,
- const ObjCCategoryDecl *C= 0) const;
- ObjCMethodDecl *lookupInstanceMethod(Selector Sel,
- bool shallowCategoryLookup = false) const {
- return lookupMethod(Sel, true/*isInstance*/, shallowCategoryLookup);
+ bool shallowCategoryLookup = false,
+ bool followSuper = true,
+ const ObjCCategoryDecl *C = nullptr) const;
+
+ /// Lookup an instance method for a given selector.
+ ObjCMethodDecl *lookupInstanceMethod(Selector Sel) const {
+ return lookupMethod(Sel, true/*isInstance*/);
}
- ObjCMethodDecl *lookupClassMethod(Selector Sel,
- bool shallowCategoryLookup = false) const {
- return lookupMethod(Sel, false/*isInstance*/, shallowCategoryLookup);
+
+ /// Lookup a class method for a given selector.
+ ObjCMethodDecl *lookupClassMethod(Selector Sel) const {
+ return lookupMethod(Sel, false/*isInstance*/);
}
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
@@ -1167,7 +1314,9 @@ public:
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
const ObjCCategoryDecl *Cat) const {
return lookupMethod(Sel, true/*isInstance*/,
- false/*shallowCategoryLookup*/, Cat);
+ false/*shallowCategoryLookup*/,
+ true /* followsSuper */,
+ Cat);
}
SourceLocation getEndOfDefinitionLoc() const {
@@ -1196,15 +1345,17 @@ public:
bool lookupCategory,
bool RHSIsQualifiedID = false);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C class.
- ObjCInterfaceDecl *getCanonicalDecl() { return getFirstDecl(); }
+ ObjCInterfaceDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCInterfaceDecl *getCanonicalDecl() const { return getFirstDecl(); }
// Low-level accessor
@@ -1217,6 +1368,10 @@ public:
friend class ASTReader;
friend class ASTDeclReader;
friend class ASTDeclWriter;
+
+private:
+ const ObjCInterfaceDecl *findInterfaceWithDesignatedInitializers() const;
+ bool inheritsDesignatedInitializers() const;
};
/// ObjCIvarDecl - Represents an ObjC instance variable. In general, ObjC
@@ -1235,7 +1390,7 @@ public:
/// }
///
class ObjCIvarDecl : public FieldDecl {
- virtual void anchor();
+ void anchor() override;
public:
enum AccessControl {
@@ -1246,21 +1401,18 @@ private:
ObjCIvarDecl(ObjCContainerDecl *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, TypeSourceInfo *TInfo, AccessControl ac, Expr *BW,
- bool synthesized,
- bool backingIvarReferencedInAccessor)
+ bool synthesized)
: FieldDecl(ObjCIvar, DC, StartLoc, IdLoc, Id, T, TInfo, BW,
/*Mutable=*/false, /*HasInit=*/ICIS_NoInit),
- NextIvar(0), DeclAccess(ac), Synthesized(synthesized),
- BackingIvarReferencedInAccessor(backingIvarReferencedInAccessor) {}
+ NextIvar(nullptr), DeclAccess(ac), Synthesized(synthesized) {}
public:
static ObjCIvarDecl *Create(ASTContext &C, ObjCContainerDecl *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo,
- AccessControl ac, Expr *BW = NULL,
- bool synthesized=false,
- bool backingIvarReferencedInAccessor=false);
+ AccessControl ac, Expr *BW = nullptr,
+ bool synthesized=false);
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -1282,13 +1434,6 @@ public:
return DeclAccess == None ? Protected : AccessControl(DeclAccess);
}
- void setBackingIvarReferencedInAccessor(bool val) {
- BackingIvarReferencedInAccessor = val;
- }
- bool getBackingIvarReferencedInAccessor() const {
- return BackingIvarReferencedInAccessor;
- }
-
void setSynthesize(bool synth) { Synthesized = synth; }
bool getSynthesize() const { return Synthesized; }
@@ -1303,18 +1448,17 @@ private:
// NOTE: VC++ treats enums as signed, avoid using the AccessControl enum
unsigned DeclAccess : 3;
unsigned Synthesized : 1;
- unsigned BackingIvarReferencedInAccessor : 1;
};
/// \brief Represents a field declaration created by an \@defs(...).
class ObjCAtDefsFieldDecl : public FieldDecl {
- virtual void anchor();
+ void anchor() override;
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
QualType T, Expr *BW)
: FieldDecl(ObjCAtDefsField, DC, StartLoc, IdLoc, Id, T,
- /*TInfo=*/0, // FIXME: Do ObjCAtDefs have declarators ?
+ /*TInfo=*/nullptr, // FIXME: Do ObjCAtDefs have declarators ?
BW, /*Mutable=*/false, /*HasInit=*/ICIS_NoInit) {}
public:
@@ -1362,7 +1506,7 @@ public:
///
class ObjCProtocolDecl : public ObjCContainerDecl,
public Redeclarable<ObjCProtocolDecl> {
- virtual void anchor();
+ void anchor() override;
struct DefinitionData {
// \brief The declaration that defines this protocol.
@@ -1384,20 +1528,20 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
return *Data.getPointer();
}
- ObjCProtocolDecl(DeclContext *DC, IdentifierInfo *Id,
+ ObjCProtocolDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
SourceLocation nameLoc, SourceLocation atStartLoc,
ObjCProtocolDecl *PrevDecl);
void allocateDefinitionData();
typedef Redeclarable<ObjCProtocolDecl> redeclarable_base;
- virtual ObjCProtocolDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ ObjCProtocolDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual ObjCProtocolDecl *getPreviousDeclImpl() {
+ ObjCProtocolDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual ObjCProtocolDecl *getMostRecentDeclImpl() {
+ ObjCProtocolDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -1409,12 +1553,17 @@ public:
ObjCProtocolDecl *PrevDecl);
static ObjCProtocolDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
+
const ObjCProtocolList &getReferencedProtocols() const {
assert(hasDefinition() && "No definition available!");
return data().ReferencedProtocols;
}
typedef ObjCProtocolList::iterator protocol_iterator;
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
protocol_iterator protocol_begin() const {
if (!hasDefinition())
return protocol_iterator();
@@ -1428,6 +1577,11 @@ public:
return data().ReferencedProtocols.end();
}
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
if (!hasDefinition())
return protocol_loc_iterator();
@@ -1486,12 +1640,12 @@ public:
/// \brief Retrieve the definition of this protocol, if any.
ObjCProtocolDecl *getDefinition() {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Retrieve the definition of this protocol, if any.
const ObjCProtocolDecl *getDefinition() const {
- return hasDefinition()? Data.getPointer()->Definition : 0;
+ return hasDefinition()? Data.getPointer()->Definition : nullptr;
}
/// \brief Determine whether this particular declaration is also the
@@ -1503,29 +1657,35 @@ public:
/// \brief Starts the definition of this Objective-C protocol.
void startDefinition();
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ /// Produce a name to be used for protocol's metadata. It comes either via
+ /// objc_runtime_name attribute or protocol name.
+ StringRef getObjCRuntimeNameAsString() const;
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
if (isThisDeclarationADefinition())
return ObjCContainerDecl::getSourceRange();
return SourceRange(getAtStartLoc(), getLocation());
}
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
/// Retrieves the canonical declaration of this Objective-C protocol.
- ObjCProtocolDecl *getCanonicalDecl() { return getFirstDecl(); }
+ ObjCProtocolDecl *getCanonicalDecl() override { return getFirstDecl(); }
const ObjCProtocolDecl *getCanonicalDecl() const { return getFirstDecl(); }
- virtual void collectPropertiesToImplement(PropertyMap &PM,
- PropertyDeclOrder &PO) const;
-
-void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
+ void collectPropertiesToImplement(PropertyMap &PM,
+ PropertyDeclOrder &PO) const override;
+
+ void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
+ ProtocolPropertyMap &PM) const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
@@ -1553,7 +1713,7 @@ void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
/// don't support this level of dynamism, which is both powerful and dangerous.
///
class ObjCCategoryDecl : public ObjCContainerDecl {
- virtual void anchor();
+ void anchor() override;
/// Interface belonging to this category
ObjCInterfaceDecl *ClassInterface;
@@ -1578,7 +1738,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
SourceLocation IvarLBraceLoc=SourceLocation(),
SourceLocation IvarRBraceLoc=SourceLocation())
: ObjCContainerDecl(ObjCCategory, DC, Id, ClassNameLoc, AtLoc),
- ClassInterface(IDecl), NextClassCategory(0),
+ ClassInterface(IDecl), NextClassCategory(nullptr),
CategoryNameLoc(CategoryNameLoc),
IvarLBraceLoc(IvarLBraceLoc), IvarRBraceLoc(IvarRBraceLoc) {
}
@@ -1613,10 +1773,22 @@ public:
}
typedef ObjCProtocolList::iterator protocol_iterator;
- protocol_iterator protocol_begin() const {return ReferencedProtocols.begin();}
+ typedef llvm::iterator_range<protocol_iterator> protocol_range;
+
+ protocol_range protocols() const {
+ return protocol_range(protocol_begin(), protocol_end());
+ }
+ protocol_iterator protocol_begin() const {
+ return ReferencedProtocols.begin();
+ }
protocol_iterator protocol_end() const { return ReferencedProtocols.end(); }
unsigned protocol_size() const { return ReferencedProtocols.size(); }
typedef ObjCProtocolList::loc_iterator protocol_loc_iterator;
+ typedef llvm::iterator_range<protocol_loc_iterator> protocol_loc_range;
+
+ protocol_loc_range protocol_locs() const {
+ return protocol_loc_range(protocol_loc_begin(), protocol_loc_end());
+ }
protocol_loc_iterator protocol_loc_begin() const {
return ReferencedProtocols.loc_begin();
}
@@ -1632,9 +1804,12 @@ public:
return NextClassCategory;
}
- bool IsClassExtension() const { return getIdentifier() == 0; }
+ bool IsClassExtension() const { return getIdentifier() == nullptr; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
@@ -1664,7 +1839,7 @@ public:
};
class ObjCImplDecl : public ObjCContainerDecl {
- virtual void anchor();
+ void anchor() override;
/// Class interface for this class/category implementation
ObjCInterfaceDecl *ClassInterface;
@@ -1674,7 +1849,8 @@ protected:
ObjCInterfaceDecl *classInterface,
SourceLocation nameLoc, SourceLocation atStartLoc)
: ObjCContainerDecl(DK, DC,
- classInterface? classInterface->getIdentifier() : 0,
+ classInterface? classInterface->getIdentifier()
+ : nullptr,
nameLoc, atStartLoc),
ClassInterface(classInterface) {}
@@ -1701,6 +1877,12 @@ public:
// Iterator access to properties.
typedef specific_decl_iterator<ObjCPropertyImplDecl> propimpl_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyImplDecl>>
+ propimpl_range;
+
+ propimpl_range property_impls() const {
+ return propimpl_range(propimpl_begin(), propimpl_end());
+ }
propimpl_iterator propimpl_begin() const {
return propimpl_iterator(decls_begin());
}
@@ -1728,7 +1910,7 @@ public:
///
/// ObjCCategoryImplDecl
class ObjCCategoryImplDecl : public ObjCImplDecl {
- virtual void anchor();
+ void anchor() override;
// Category name
IdentifierInfo *Id;
@@ -1753,8 +1935,8 @@ public:
/// getIdentifier - Get the identifier that names the category
/// interface associated with this implementation.
- /// FIXME: This is a bad API, we are overriding the NamedDecl::getIdentifier()
- /// to mean something different. For example:
+ /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
+ /// with a different meaning. For example:
/// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
/// returns the class interface name, whereas
/// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
@@ -1771,11 +1953,9 @@ public:
/// getName - Get the name of identifier for the class interface associated
/// with this implementation as a StringRef.
//
- // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
- // something different.
- StringRef getName() const {
- return Id ? Id->getNameStart() : "";
- }
+ // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+ // meaning.
+ StringRef getName() const { return Id ? Id->getName() : StringRef(); }
/// @brief Get the name of the class associated with this interface.
//
@@ -1802,13 +1982,16 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCCategoryImplDecl &CID);
/// \@end
/// @endcode
///
-/// Typically, instance variables are specified in the class interface,
-/// *not* in the implementation. Nevertheless (for legacy reasons), we
-/// allow instance variables to be specified in the implementation. When
-/// specified, they need to be *identical* to the interface.
+/// In a non-fragile runtime, instance variables can appear in the class
+/// interface, class extensions (nameless categories), and in the implementation
+/// itself, as well as being synthesized as backing storage for properties.
///
+/// In a fragile runtime, instance variables are specified in the class
+/// interface, \em not in the implementation. Nevertheless (for legacy reasons),
+/// we allow instance variables to be specified in the implementation. When
+/// specified, they need to be \em identical to the interface.
class ObjCImplementationDecl : public ObjCImplDecl {
- virtual void anchor();
+ void anchor() override;
/// Implementation Class's super class.
ObjCInterfaceDecl *SuperClass;
SourceLocation SuperLoc;
@@ -1839,7 +2022,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
: ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
IvarRBraceLoc(IvarRBraceLoc),
- IvarInitializers(0), NumIvarInitializers(0),
+ IvarInitializers(nullptr), NumIvarInitializers(0),
HasNonZeroConstructors(false), HasDestructors(false) {}
public:
static ObjCImplementationDecl *Create(ASTContext &C, DeclContext *DC,
@@ -1859,6 +2042,14 @@ public:
/// init_const_iterator - Iterates through the ivar initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
+ typedef llvm::iterator_range<init_iterator> init_range;
+ typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+ init_range inits() { return init_range(init_begin(), init_end()); }
+ init_const_range inits() const {
+ return init_const_range(init_begin(), init_end());
+ }
+
/// init_begin() - Retrieve an iterator to the first initializer.
init_iterator init_begin() { return IvarInitializers; }
/// begin() - Retrieve an iterator to the first initializer.
@@ -1904,8 +2095,8 @@ public:
/// getName - Get the name of identifier for the class interface associated
/// with this implementation as a StringRef.
//
- // FIXME: This is a bad API, we are overriding the NamedDecl::getName, to mean
- // something different.
+ // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
+ // meaning.
StringRef getName() const {
assert(getIdentifier() && "Name is not a simple identifier");
return getIdentifier()->getName();
@@ -1917,6 +2108,10 @@ public:
std::string getNameAsString() const {
return getName();
}
+
+ /// Produce a name to be used for class's metadata. It comes either via
+ /// class's objc_runtime_name attribute or class name.
+ StringRef getObjCRuntimeNameAsString() const;
const ObjCInterfaceDecl *getSuperClass() const { return SuperClass; }
ObjCInterfaceDecl *getSuperClass() { return SuperClass; }
@@ -1930,6 +2125,9 @@ public:
SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; }
typedef specific_decl_iterator<ObjCIvarDecl> ivar_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<ObjCIvarDecl>> ivar_range;
+
+ ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); }
ivar_iterator ivar_begin() const {
return ivar_iterator(decls_begin());
}
@@ -1955,7 +2153,7 @@ raw_ostream &operator<<(raw_ostream &OS, const ObjCImplementationDecl &ID);
/// ObjCCompatibleAliasDecl - Represents alias of a class. This alias is
/// declared as \@compatibility_alias alias class.
class ObjCCompatibleAliasDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// Class that this is an alias of.
ObjCInterfaceDecl *AliasedClass;
@@ -1986,7 +2184,7 @@ public:
/// \@property (assign, readwrite) int MyProperty;
/// \endcode
class ObjCPropertyDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
public:
enum PropertyAttributeKind {
OBJC_PR_noattr = 0x00,
@@ -2038,7 +2236,9 @@ private:
PropertyImplementation(None),
GetterName(Selector()),
SetterName(Selector()),
- GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {}
+ GetterMethodDecl(nullptr), SetterMethodDecl(nullptr),
+ PropertyIvarDecl(nullptr) {}
+
public:
static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -2145,7 +2345,7 @@ public:
return PropertyIvarDecl;
}
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(AtLoc, getLocation());
}
@@ -2202,7 +2402,7 @@ private:
SourceLocation ivarLoc)
: Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc),
IvarLoc(ivarLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl),
- GetterCXXConstructor(0), SetterCXXAssignment(0) {
+ GetterCXXConstructor(nullptr), SetterCXXAssignment(nullptr) {
assert (PK == Dynamic || PropertyIvarDecl);
}
@@ -2215,8 +2415,8 @@ public:
SourceLocation ivarLoc);
static ObjCPropertyImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY;
+
+ SourceRange getSourceRange() const override LLVM_READONLY;
SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; }
void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h
index 42fe907aa174..1b329dcd0052 100644
--- a/include/clang/AST/DeclOpenMP.h
+++ b/include/clang/AST/DeclOpenMP.h
@@ -47,10 +47,10 @@ class OMPThreadPrivateDecl : public Decl {
NumVars);
}
- llvm::MutableArrayRef<Expr *> getVars() {
- return llvm::MutableArrayRef<Expr *>(
- reinterpret_cast<Expr **>(this + 1),
- NumVars);
+ MutableArrayRef<Expr *> getVars() {
+ return MutableArrayRef<Expr *>(
+ reinterpret_cast<Expr **>(this + 1),
+ NumVars);
}
void setVars(ArrayRef<Expr *> VL);
@@ -62,11 +62,20 @@ public:
static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C,
unsigned ID, unsigned N);
- typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
+ typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+ typedef llvm::iterator_range<varlist_iterator> varlist_range;
+ typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
unsigned varlist_size() const { return NumVars; }
bool varlist_empty() const { return NumVars == 0; }
+
+ varlist_range varlists() {
+ return varlist_range(varlist_begin(), varlist_end());
+ }
+ varlist_const_range varlists() const {
+ return varlist_const_range(varlist_begin(), varlist_end());
+ }
varlist_iterator varlist_begin() { return getVars().begin(); }
varlist_iterator varlist_end() { return getVars().end(); }
varlist_const_iterator varlist_begin() const { return getVars().begin(); }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 24bd28a75aaa..980a06e35b70 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -86,11 +86,11 @@ public:
unsigned size() const { return NumParams; }
- llvm::ArrayRef<NamedDecl*> asArray() {
- return llvm::ArrayRef<NamedDecl*>(begin(), size());
+ ArrayRef<NamedDecl*> asArray() {
+ return ArrayRef<NamedDecl*>(begin(), size());
}
- llvm::ArrayRef<const NamedDecl*> asArray() const {
- return llvm::ArrayRef<const NamedDecl*>(begin(), size());
+ ArrayRef<const NamedDecl*> asArray() const {
+ return ArrayRef<const NamedDecl*>(begin(), size());
}
NamedDecl* getParam(unsigned Idx) {
@@ -203,8 +203,8 @@ public:
const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
/// \brief Produce this as an array ref.
- llvm::ArrayRef<TemplateArgument> asArray() const {
- return llvm::ArrayRef<TemplateArgument>(data(), size());
+ ArrayRef<TemplateArgument> asArray() const {
+ return ArrayRef<TemplateArgument>(data(), size());
}
/// \brief Retrieve the number of template arguments in this
@@ -227,18 +227,20 @@ public:
/// The TemplateDecl class stores the list of template parameters and a
/// reference to the templated scoped declaration: the underlying AST node.
class TemplateDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
protected:
// This is probably never used.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0) { }
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+ TemplateParams(nullptr) {}
// Construct a template decl with the given name and parameters.
// Used when there is not templated element (tt-params, alias?).
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params) { }
+ : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
+ TemplateParams(Params) {}
// Construct a template decl with name, parameters, and templated element.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -261,7 +263,7 @@ public:
return K >= firstTemplate && K <= lastTemplate;
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(TemplateParams->getTemplateLoc(),
TemplatedDecl->getSourceRange().getEnd());
}
@@ -274,8 +276,8 @@ public:
/// \brief Initialize the underlying templated declaration and
/// template parameters.
void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) {
- assert(TemplatedDecl == 0 && "TemplatedDecl already set!");
- assert(TemplateParams == 0 && "TemplateParams already set!");
+ assert(!TemplatedDecl && "TemplatedDecl already set!");
+ assert(!TemplateParams && "TemplateParams already set!");
TemplatedDecl = templatedDecl;
TemplateParams = templateParams;
}
@@ -378,16 +380,15 @@ public:
}
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->data(),
- TemplateArguments->size(),
+ Profile(ID, TemplateArguments->asArray(),
Function->getASTContext());
}
static void
- Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs, ASTContext &Context) {
- ID.AddInteger(NumTemplateArgs);
- for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+ ASTContext &Context) {
+ ID.AddInteger(TemplateArgs.size());
+ for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
TemplateArgs[Arg].Profile(ID, Context);
}
};
@@ -530,13 +531,13 @@ class RedeclarableTemplateDecl : public TemplateDecl,
public Redeclarable<RedeclarableTemplateDecl>
{
typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- virtual RedeclarableTemplateDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
+ RedeclarableTemplateDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
+ RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -595,11 +596,10 @@ protected:
template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- const TemplateArgument *Args, unsigned NumArgs,
- void *&InsertPos);
+ ArrayRef<TemplateArgument> Args, void *&InsertPos);
struct CommonBase {
- CommonBase() : InstantiatedFromMember(0, false) { }
+ CommonBase() : InstantiatedFromMember(nullptr, false) { }
/// \brief The template from which this was most
/// directly instantiated (or null).
@@ -622,16 +622,19 @@ protected:
virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
+ RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl)
+ : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
+ Common() {}
public:
template <class decl_type> friend class RedeclarableTemplate;
/// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDecl(); }
+ RedeclarableTemplateDecl *getCanonicalDecl() override {
+ return getFirstDecl();
+ }
const RedeclarableTemplateDecl *getCanonicalDecl() const {
return getFirstDecl();
}
@@ -710,9 +713,11 @@ public:
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
using redeclarable_base::isFirstDecl;
@@ -769,11 +774,13 @@ protected:
uint32_t *LazySpecializations;
};
- FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
+ FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
+ Decl) {}
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -810,10 +817,10 @@ public:
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
- FunctionDecl *findSpecialization(const TemplateArgument *Args,
- unsigned NumArgs, void *&InsertPos);
+ FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
+ void *&InsertPos);
- FunctionTemplateDecl *getCanonicalDecl() {
+ FunctionTemplateDecl *getCanonicalDecl() override {
return cast<FunctionTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -842,7 +849,11 @@ public:
}
typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
}
@@ -892,12 +903,9 @@ public:
/// This class is inheritedly privately by different kinds of template
/// parameters and is not part of the Decl hierarchy. Just a facility.
class TemplateParmPosition {
-protected:
- // FIXME: This should probably never be called, but it's here as
- TemplateParmPosition()
- : Depth(0), Position(0)
- { /* llvm_unreachable("Cannot create positionless template parameter"); */ }
+ TemplateParmPosition() LLVM_DELETED_FUNCTION;
+protected:
TemplateParmPosition(unsigned D, unsigned P)
: Depth(D), Position(P)
{ }
@@ -967,7 +975,7 @@ public:
/// \brief Determine whether this template parameter has a default
/// argument.
- bool hasDefaultArgument() const { return DefaultArgument != 0; }
+ bool hasDefaultArgument() const { return DefaultArgument != nullptr; }
/// \brief Retrieve the default argument, if any.
QualType getDefaultArgument() const { return DefaultArgument->getType(); }
@@ -992,7 +1000,7 @@ public:
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
- DefaultArgument = 0;
+ DefaultArgument = nullptr;
InheritedDefault = false;
}
@@ -1009,7 +1017,7 @@ public:
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const;
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1046,7 +1054,7 @@ class NonTypeTemplateParmDecl
IdentifierInfo *Id, QualType T,
bool ParameterPack, TypeSourceInfo *TInfo)
: DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(nullptr, false),
ParameterPack(ParameterPack), ExpandedParameterPack(false),
NumExpandedTypes(0)
{ }
@@ -1086,12 +1094,12 @@ public:
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
- return DefaultArgumentAndInherited.getPointer() != 0;
+ return DefaultArgumentAndInherited.getPointer() != nullptr;
}
/// \brief Retrieve the default argument, if any.
@@ -1118,7 +1126,7 @@ public:
/// \brief Removes the default argument of this template parameter.
void removeDefaultArgument() {
- DefaultArgumentAndInherited.setPointer(0);
+ DefaultArgumentAndInherited.setPointer(nullptr);
DefaultArgumentAndInherited.setInt(false);
}
@@ -1206,7 +1214,7 @@ public:
class TemplateTemplateParmDecl : public TemplateDecl,
protected TemplateParmPosition
{
- virtual void anchor();
+ void anchor() override;
/// DefaultArgument - The default template argument, if any.
TemplateArgumentLoc DefaultArgument;
@@ -1347,7 +1355,7 @@ public:
DefaultArgumentWasInherited = false;
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
SourceLocation End = getLocation();
if (hasDefaultArgument() && !defaultArgumentWasInherited())
End = getDefaultArgument().getSourceRange().getEnd();
@@ -1405,7 +1413,7 @@ class ClassTemplateSpecializationDecl
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo()
- : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
};
/// \brief Further info for explicit template specialization/instantiation.
@@ -1431,7 +1439,7 @@ protected:
unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
- explicit ClassTemplateSpecializationDecl(Kind DK);
+ explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
public:
static ClassTemplateSpecializationDecl *
@@ -1444,10 +1452,14 @@ public:
static ClassTemplateSpecializationDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
+ // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
+ // different "most recent" declaration from this function for the same
+ // declaration, because we don't override getMostRecentDeclImpl(). But
+ // it's not clear that we should override that, because the most recent
+ // declaration as a CXXRecordDecl sometimes is the injected-class-name.
ClassTemplateSpecializationDecl *getMostRecentDecl() {
CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
this)->getMostRecentDecl();
@@ -1516,17 +1528,11 @@ public:
llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>
getInstantiatedFrom() const {
- if (getSpecializationKind() != TSK_ImplicitInstantiation &&
- getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
- getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
+ if (!isTemplateInstantiation(getSpecializationKind()))
return llvm::PointerUnion<ClassTemplateDecl *,
ClassTemplatePartialSpecializationDecl *>();
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<ClassTemplateDecl*>();
+ return getSpecializedTemplateOrPartial();
}
/// \brief Retrieve the class template or class template partial
@@ -1592,7 +1598,7 @@ public:
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
}
/// \brief Gets the location of the extern keyword, if present.
@@ -1617,17 +1623,17 @@ public:
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+ Profile(ID, TemplateArgs->asArray(), getASTContext());
}
static void
- Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs, ASTContext &Context) {
- ID.AddInteger(NumTemplateArgs);
- for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
+ ASTContext &Context) {
+ ID.AddInteger(TemplateArgs.size());
+ for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
TemplateArgs[Arg].Profile(ID, Context);
}
@@ -1643,7 +1649,7 @@ public:
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The list of template parameters
TemplateParameterList* TemplateParams;
@@ -1671,9 +1677,10 @@ class ClassTemplatePartialSpecializationDecl
const ASTTemplateArgumentListInfo *ArgsAsWritten,
ClassTemplatePartialSpecializationDecl *PrevDecl);
- ClassTemplatePartialSpecializationDecl()
- : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
- TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) { }
+ ClassTemplatePartialSpecializationDecl(ASTContext &C)
+ : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
+ TemplateParams(nullptr), ArgsAsWritten(nullptr),
+ InstantiatedFromMember(nullptr, false) {}
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1832,15 +1839,12 @@ protected:
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
+ ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
- ClassTemplateDecl(EmptyShell Empty)
- : RedeclarableTemplateDecl(ClassTemplate, 0, SourceLocation(),
- DeclarationName(), 0, 0) { }
-
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -1872,14 +1876,13 @@ public:
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
ClassTemplateSpecializationDecl *
- findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
- void *&InsertPos);
+ findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
/// \brief Insert the specified specialization knowing that it is not already
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
- ClassTemplateDecl *getCanonicalDecl() {
+ ClassTemplateDecl *getCanonicalDecl() override {
return cast<ClassTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -1919,8 +1922,7 @@ public:
/// \brief Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
ClassTemplatePartialSpecializationDecl *
- findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
- void *&InsertPos);
+ findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
/// \brief Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
@@ -1970,6 +1972,11 @@ public:
QualType getInjectedClassNameSpecialization();
typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
@@ -1979,17 +1986,6 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- typedef SpecIterator<ClassTemplatePartialSpecializationDecl>
- partial_spec_iterator;
-
- partial_spec_iterator partial_spec_begin() {
- return makeSpecIterator(getPartialSpecializations(), false);
- }
-
- partial_spec_iterator partial_spec_end() {
- return makeSpecIterator(getPartialSpecializations(), true);
- }
-
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ClassTemplate; }
@@ -2045,7 +2041,7 @@ private:
FriendTemplateDecl(EmptyShell Empty)
: Decl(Decl::FriendTemplate, Empty),
NumParams(0),
- Params(0)
+ Params(nullptr)
{}
public:
@@ -2105,11 +2101,13 @@ class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
protected:
typedef CommonBase Common;
- TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(TypeAliasTemplate, DC, L, Name, Params, Decl) { }
+ TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
+ Decl) {}
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2122,7 +2120,7 @@ public:
}
- TypeAliasTemplateDecl *getCanonicalDecl() {
+ TypeAliasTemplateDecl *getCanonicalDecl() override {
return cast<TypeAliasTemplateDecl>(
RedeclarableTemplateDecl::getCanonicalDecl());
}
@@ -2172,7 +2170,7 @@ public:
/// \brief Declaration of a function specialization at template class scope.
///
-/// This is a non standard extension needed to support MSVC.
+/// This is a non-standard extension needed to support MSVC.
///
/// For example:
/// \code
@@ -2214,9 +2212,8 @@ public:
CXXMethodDecl *FD,
bool HasExplicitTemplateArgs,
TemplateArgumentListInfo TemplateArgs) {
- return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD,
- HasExplicitTemplateArgs,
- TemplateArgs);
+ return new (C, DC) ClassScopeFunctionSpecializationDecl(
+ DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
}
static ClassScopeFunctionSpecializationDecl *
@@ -2279,7 +2276,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
SourceLocation TemplateKeywordLoc;
ExplicitSpecializationInfo()
- : TypeAsWritten(0), ExternLoc(), TemplateKeywordLoc() {}
+ : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
};
/// \brief Further info for explicit template specialization/instantiation.
@@ -2298,14 +2295,14 @@ class VarTemplateSpecializationDecl : public VarDecl,
unsigned SpecializationKind : 3;
protected:
- VarTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC,
+ VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
VarTemplateDecl *SpecializedTemplate,
QualType T, TypeSourceInfo *TInfo,
StorageClass S, const TemplateArgument *Args,
unsigned NumArgs);
- explicit VarTemplateSpecializationDecl(Kind DK);
+ explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
public:
static VarTemplateSpecializationDecl *
@@ -2316,9 +2313,8 @@ public:
static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
unsigned ID);
- virtual void getNameForDiagnostic(raw_ostream &OS,
- const PrintingPolicy &Policy,
- bool Qualified) const;
+ void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool Qualified) const override;
VarTemplateSpecializationDecl *getMostRecentDecl() {
VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
@@ -2461,7 +2457,7 @@ public:
/// \brief Gets the type of this specialization as it was written by
/// the user, if it was so written.
TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : 0;
+ return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
}
/// \brief Gets the location of the extern keyword, if present.
@@ -2487,14 +2483,14 @@ public:
}
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
+ Profile(ID, TemplateArgs->asArray(), getASTContext());
}
static void Profile(llvm::FoldingSetNodeID &ID,
- const TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs, ASTContext &Context) {
- ID.AddInteger(NumTemplateArgs);
- for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
+ ArrayRef<TemplateArgument> TemplateArgs,
+ ASTContext &Context) {
+ ID.AddInteger(TemplateArgs.size());
+ for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
TemplateArgs[Arg].Profile(ID, Context);
}
@@ -2510,7 +2506,7 @@ public:
class VarTemplatePartialSpecializationDecl
: public VarTemplateSpecializationDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The list of template parameters
TemplateParameterList *TemplateParams;
@@ -2534,9 +2530,10 @@ class VarTemplatePartialSpecializationDecl
StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
const ASTTemplateArgumentListInfo *ArgInfos);
- VarTemplatePartialSpecializationDecl()
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization),
- TemplateParams(0), ArgsAsWritten(0), InstantiatedFromMember(0, false) {}
+ VarTemplatePartialSpecializationDecl(ASTContext &Context)
+ : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
+ TemplateParams(nullptr), ArgsAsWritten(nullptr),
+ InstantiatedFromMember(nullptr, false) {}
public:
static VarTemplatePartialSpecializationDecl *
@@ -2677,15 +2674,12 @@ protected:
llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- VarTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(VarTemplate, DC, L, Name, Params, Decl) {}
+ VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
+ DeclarationName Name, TemplateParameterList *Params,
+ NamedDecl *Decl)
+ : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
- VarTemplateDecl(EmptyShell Empty)
- : RedeclarableTemplateDecl(VarTemplate, 0, SourceLocation(),
- DeclarationName(), 0, 0) {}
-
- CommonBase *newCommon(ASTContext &C) const;
+ CommonBase *newCommon(ASTContext &C) const override;
Common *getCommonPtr() const {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -2708,8 +2702,8 @@ public:
/// \brief Create a variable template node.
static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl,
- VarTemplateDecl *PrevDecl);
+ TemplateParameterList *Params,
+ VarDecl *Decl);
/// \brief Create an empty variable template node.
static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2717,14 +2711,13 @@ public:
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
VarTemplateSpecializationDecl *
- findSpecialization(const TemplateArgument *Args, unsigned NumArgs,
- void *&InsertPos);
+ findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
/// \brief Insert the specified specialization knowing that it is not already
/// in. InsertPos must be obtained from findSpecialization.
void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
- VarTemplateDecl *getCanonicalDecl() {
+ VarTemplateDecl *getCanonicalDecl() override {
return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
}
const VarTemplateDecl *getCanonicalDecl() const {
@@ -2754,8 +2747,7 @@ public:
/// \brief Return the partial specialization with the provided arguments if it
/// exists, otherwise return the insertion point.
VarTemplatePartialSpecializationDecl *
- findPartialSpecialization(const TemplateArgument *Args, unsigned NumArgs,
- void *&InsertPos);
+ findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
/// \brief Insert the specified partial specialization knowing that it is not
/// already in. InsertPos must be obtained from findPartialSpecialization.
@@ -2780,6 +2772,11 @@ public:
VarTemplatePartialSpecializationDecl *D);
typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
+ typedef llvm::iterator_range<spec_iterator> spec_range;
+
+ spec_range specializations() const {
+ return spec_range(spec_begin(), spec_end());
+ }
spec_iterator spec_begin() const {
return makeSpecIterator(getSpecializations(), false);
@@ -2789,17 +2786,6 @@ public:
return makeSpecIterator(getSpecializations(), true);
}
- typedef SpecIterator<VarTemplatePartialSpecializationDecl>
- partial_spec_iterator;
-
- partial_spec_iterator partial_spec_begin() {
- return makeSpecIterator(getPartialSpecializations(), false);
- }
-
- partial_spec_iterator partial_spec_end() {
- return makeSpecIterator(getPartialSpecializations(), true);
- }
-
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == VarTemplate; }
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 00766c27c136..3076b30cd377 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -29,6 +29,7 @@ namespace clang {
class DeclarationNameExtra;
class IdentifierInfo;
class MultiKeywordSelector;
+ enum OverloadedOperatorKind : int;
class QualType;
class Type;
class TypeSourceInfo;
@@ -116,20 +117,20 @@ private:
NameKind Kind = getNameKind();
if (Kind >= CXXConstructorName && Kind <= CXXConversionFunctionName)
return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
/// getAsCXXOperatorIdName
CXXOperatorIdName *getAsCXXOperatorIdName() const {
if (getNameKind() == CXXOperatorName)
return reinterpret_cast<CXXOperatorIdName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
if (getNameKind() == CXXLiteralOperatorName)
return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
- return 0;
+ return nullptr;
}
// Construct a declaration name from the name of a C++ constructor,
@@ -221,7 +222,7 @@ public:
IdentifierInfo *getAsIdentifierInfo() const {
if (isIdentifier())
return reinterpret_cast<IdentifierInfo *>(Ptr);
- return 0;
+ return nullptr;
}
/// getAsOpaqueInteger - Get the representation of this declaration
diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h
index 004b45da0f34..63047ec4db84 100644
--- a/include/clang/AST/DependentDiagnostic.h
+++ b/include/clang/AST/DependentDiagnostic.h
@@ -123,7 +123,7 @@ private:
/// An iterator over the dependent diagnostics in a dependent context.
class DeclContext::ddiag_iterator {
public:
- ddiag_iterator() : Ptr(0) {}
+ ddiag_iterator() : Ptr(nullptr) {}
explicit ddiag_iterator(DependentDiagnostic *Ptr) : Ptr(Ptr) {}
typedef DependentDiagnostic *value_type;
@@ -171,18 +171,16 @@ private:
DependentDiagnostic *Ptr;
};
-inline DeclContext::ddiag_iterator DeclContext::ddiag_begin() const {
+inline DeclContext::ddiag_range DeclContext::ddiags() const {
assert(isDependentContext()
&& "cannot iterate dependent diagnostics of non-dependent context");
const DependentStoredDeclsMap *Map
= static_cast<DependentStoredDeclsMap*>(getPrimaryContext()->getLookupPtr());
- if (!Map) return ddiag_iterator();
- return ddiag_iterator(Map->FirstDiagnostic);
-}
+ if (!Map)
+ return ddiag_range();
-inline DeclContext::ddiag_iterator DeclContext::ddiag_end() const {
- return ddiag_iterator();
+ return ddiag_range(ddiag_iterator(Map->FirstDiagnostic), ddiag_iterator());
}
}
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index f2648b9a4a04..b4bb0b6b6440 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -293,8 +293,8 @@ public:
/// \param Loc [in,out] - A source location which *may* be filled
/// in with the location of the expression making this a
/// non-modifiable lvalue, if specified.
- isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ isModifiableLvalueResult
+ isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
/// \brief The return type of classify(). Represents the C++11 expression
/// taxonomy.
@@ -372,7 +372,7 @@ public:
/// lvalues and xvalues are collectively referred to as glvalues, while
/// prvalues and xvalues together form rvalues.
Classification Classify(ASTContext &Ctx) const {
- return ClassifyImpl(Ctx, 0);
+ return ClassifyImpl(Ctx, nullptr);
}
/// \brief ClassifyModifiable - Classify this expression according to the
@@ -483,10 +483,10 @@ public:
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
- SourceLocation *Loc = 0,
+ SourceLocation *Loc = nullptr,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ SourceLocation *Loc = nullptr) const;
/// isCXX98IntegralConstantExpr - Return true if this expression is an
/// integral constant expression in C++98. Can only be used in C++.
@@ -497,8 +497,8 @@ public:
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0,
- SourceLocation *Loc = 0) const;
+ bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
+ SourceLocation *Loc = nullptr) const;
/// isPotentialConstantExpr - Return true if this function's definition
/// might be usable in a constant expression in C++11, if it were marked
@@ -508,9 +508,22 @@ public:
SmallVectorImpl<
PartialDiagnosticAt> &Diags);
+ /// isPotentialConstantExprUnevaluted - Return true if this expression might
+ /// be usable in a constant expression in C++11 in an unevaluated context, if
+ /// it were in function FD marked constexpr. Return false if the function can
+ /// never produce a constant expression, along with diagnostics describing
+ /// why not.
+ static bool isPotentialConstantExprUnevaluated(Expr *E,
+ const FunctionDecl *FD,
+ SmallVectorImpl<
+ PartialDiagnosticAt> &Diags);
+
/// isConstantInitializer - Returns true if this expression can be emitted to
/// IR as a constant, and thus can be used as a constant initializer in C.
- bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
+ /// If this expression is not constant and Culprit is non-null,
+ /// it is used to store the address of first non constant expr.
+ bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
+ const Expr **Culprit = nullptr) const;
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
@@ -527,7 +540,7 @@ public:
/// expression *is* a constant expression, no notes will be produced.
SmallVectorImpl<PartialDiagnosticAt> *Diag;
- EvalStatus() : HasSideEffects(false), Diag(0) {}
+ EvalStatus() : HasSideEffects(false), Diag(nullptr) {}
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -584,7 +597,7 @@ public:
/// integer. This must be called on an expression that constant folds to an
/// integer.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
void EvaluateForOverflow(const ASTContext &Ctx) const;
@@ -600,6 +613,14 @@ public:
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ /// EvaluateWithSubstitution - Evaluate an expression as if from the context
+ /// of a call to the given function with the given arguments, inside an
+ /// unevaluated context. Returns true if the expression could be folded to a
+ /// constant.
+ bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+ const FunctionDecl *Callee,
+ ArrayRef<const Expr*> Args) const;
+
/// \brief Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
@@ -681,6 +702,9 @@ public:
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts() LLVM_READONLY;
+ /// Ignore casts. Strip off any CastExprs, returning their operand.
+ Expr *IgnoreCasts() LLVM_READONLY;
+
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
/// any ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts() LLVM_READONLY;
@@ -742,6 +766,11 @@ public:
const Expr *IgnoreParenCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
+ /// Strip off casts, but keep parentheses.
+ const Expr *IgnoreCasts() const LLVM_READONLY {
+ return const_cast<Expr*>(this)->IgnoreCasts();
+ }
+
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}
@@ -764,11 +793,6 @@ public:
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
- /// Skip irrelevant expressions to find what should be materialize for
- /// binding with a reference.
- const Expr *
- findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
-
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;
@@ -793,7 +817,7 @@ class OpaqueValueExpr : public Expr {
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = 0)
+ Expr *SourceExpr = nullptr)
: Expr(OpaqueValueExprClass, T, VK, OK,
T->isDependentType(),
T->isDependentType() ||
@@ -937,25 +961,19 @@ public:
computeDependence(D->getASTContext());
}
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- SourceLocation NameLoc,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
-
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- const DeclarationNameInfo &NameInfo,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ SourceLocation NameLoc, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
+
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(const ASTContext &Context,
@@ -985,7 +1003,7 @@ public:
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
if (!hasQualifier())
- return 0;
+ return nullptr;
return getInternalQualifierLoc().getNestedNameSpecifier();
}
@@ -1021,7 +1039,7 @@ public:
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!hasTemplateKWAndArgsInfo())
- return 0;
+ return nullptr;
if (hasFoundDecl())
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
@@ -1085,7 +1103,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -1100,7 +1118,7 @@ public:
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -1151,6 +1169,7 @@ public:
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
+ FuncSig,
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
@@ -1862,7 +1881,7 @@ private:
explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
: Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+ TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
public:
@@ -2213,6 +2232,13 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
arg_iterator arg_end() {
@@ -2238,9 +2264,9 @@ public:
/// this function call.
unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
- /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
- /// not, return 0.
- unsigned isBuiltinCall() const;
+ /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
+ /// of the callee. If not, return 0.
+ unsigned getBuiltinCallee() const;
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
@@ -2392,14 +2418,14 @@ public:
/// \brief Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
- bool hasQualifier() const { return getQualifier() != 0; }
+ bool hasQualifier() const { return getQualifier() != nullptr; }
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
if (!HasQualifierOrFoundDecl)
- return 0;
+ return nullptr;
return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
}
@@ -2417,7 +2443,7 @@ public:
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!HasTemplateKWAndArgsInfo)
- return 0;
+ return nullptr;
if (!HasQualifierOrFoundDecl)
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
@@ -2485,7 +2511,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2493,7 +2519,7 @@ public:
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -2633,7 +2659,7 @@ public:
private:
Stmt *Op;
- void CheckCastConsistency() const;
+ bool CastConsistency() const;
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
@@ -2664,9 +2690,7 @@ protected:
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
-#ifndef NDEBUG
- CheckCastConsistency();
-#endif
+ assert(CastConsistency());
}
/// \brief Construct an empty cast.
@@ -3422,7 +3446,7 @@ public:
/// \brief Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
- : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+ : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -3774,6 +3798,14 @@ public:
void setInit(unsigned Init, Expr *expr) {
assert(Init < getNumInits() && "Initializer access out of range!");
InitExprs[Init] = expr;
+
+ if (expr) {
+ ExprBits.TypeDependent |= expr->isTypeDependent();
+ ExprBits.ValueDependent |= expr->isValueDependent();
+ ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
+ ExprBits.ContainsUnexpandedParameterPack |=
+ expr->containsUnexpandedParameterPack();
+ }
}
/// \brief Reserve space for some number of initializers.
@@ -3824,8 +3856,8 @@ public:
return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
}
void setInitializedFieldInUnion(FieldDecl *FD) {
- assert((FD == 0
- || getInitializedFieldInUnion() == 0
+ assert((FD == nullptr
+ || getInitializedFieldInUnion() == nullptr
|| getInitializedFieldInUnion() == FD)
&& "Only one field of a union may be initialized at a time!");
ArrayFillerOrUnionFieldInit = FD;
@@ -3848,10 +3880,10 @@ public:
bool isSemanticForm() const { return AltForm.getInt(); }
InitListExpr *getSemanticForm() const {
- return isSemanticForm() ? 0 : AltForm.getPointer();
+ return isSemanticForm() ? nullptr : AltForm.getPointer();
}
InitListExpr *getSyntacticForm() const {
- return isSemanticForm() ? AltForm.getPointer() : 0;
+ return isSemanticForm() ? AltForm.getPointer() : nullptr;
}
void setSyntacticForm(InitListExpr *Init) {
@@ -3877,6 +3909,7 @@ public:
// Iterators
child_range children() {
+ // FIXME: This does not include the array filler expression.
if (InitExprs.empty()) return child_range();
return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
}
@@ -3953,7 +3986,7 @@ private:
explicit DesignatedInitExpr(unsigned NumSubExprs)
: Expr(DesignatedInitExprClass, EmptyShell()),
- NumDesignators(0), NumSubExprs(NumSubExprs), Designators(0) { }
+ NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
public:
/// A field designator, e.g., ".x".
@@ -4050,7 +4083,7 @@ public:
FieldDecl *getField() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
if (Field.NameOrField & 0x01)
- return 0;
+ return nullptr;
else
return reinterpret_cast<FieldDecl *>(Field.NameOrField);
}
@@ -4134,6 +4167,17 @@ public:
return Designators + NumDesignators;
}
+ typedef llvm::iterator_range<designators_iterator> designators_range;
+ designators_range designators() {
+ return designators_range(designators_begin(), designators_end());
+ }
+
+ typedef llvm::iterator_range<const_designators_iterator>
+ designators_const_range;
+ designators_const_range designators() const {
+ return designators_const_range(designators_begin(), designators_end());
+ }
+
typedef std::reverse_iterator<designators_iterator>
reverse_designators_iterator;
reverse_designators_iterator designators_rbegin() {
@@ -4186,18 +4230,14 @@ public:
/// and array-range designators.
unsigned getNumSubExprs() const { return NumSubExprs; }
- Expr *getSubExpr(unsigned Idx) {
+ Expr *getSubExpr(unsigned Idx) const {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+ return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
}
void setSubExpr(unsigned Idx, Expr *E) {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+ reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
}
/// \brief Replaces the designator at index @p Idx with the series
@@ -4621,7 +4661,7 @@ class PseudoObjectExpr : public Expr {
public:
/// NoResult - A value for the result index indicating that there is
/// no semantic result.
- enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U };
+ enum : unsigned { NoResult = ~0U };
static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
ArrayRef<Expr*> semantic,
@@ -4646,7 +4686,7 @@ public:
/// Return the result-bearing expression, or null if there is none.
Expr *getResultExpr() {
if (PseudoObjectExprBits.ResultIndex == 0)
- return 0;
+ return nullptr;
return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
}
const Expr *getResultExpr() const {
@@ -4713,6 +4753,16 @@ public:
BI_First = 0
};
+ // The ABI values for various atomic memory orderings.
+ enum AtomicOrderingKind {
+ AO_ABI_memory_order_relaxed = 0,
+ AO_ABI_memory_order_consume = 1,
+ AO_ABI_memory_order_acquire = 2,
+ AO_ABI_memory_order_release = 3,
+ AO_ABI_memory_order_acq_rel = 4,
+ AO_ABI_memory_order_seq_cst = 5
+ };
+
private:
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
Stmt* SubExprs[END_EXPR];
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 6356ee7aee63..3a43d6dac140 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -20,7 +20,7 @@
#include "clang/AST/TemplateBase.h"
#include "clang/AST/UnresolvedSet.h"
#include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/Lambda.h"
+#include "clang/AST/LambdaCapture.h"
#include "clang/Basic/TypeTraits.h"
#include "llvm/Support/Compiler.h"
@@ -486,7 +486,7 @@ class CXXStdInitializerListExpr : public Expr {
Stmt *SubExpr;
CXXStdInitializerListExpr(EmptyShell Empty)
- : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(0) {}
+ : Expr(CXXStdInitializerListExprClass, Empty), SubExpr(nullptr) {}
public:
CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr)
@@ -553,9 +553,9 @@ public:
CXXTypeidExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXTypeidExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
/// Determine whether this typeid has a type operand which is potentially
@@ -692,9 +692,9 @@ public:
CXXUuidofExpr(EmptyShell Empty, bool isExpr)
: Expr(CXXUuidofExprClass, Empty) {
if (isExpr)
- Operand = (Expr*)0;
+ Operand = (Expr*)nullptr;
else
- Operand = (TypeSourceInfo*)0;
+ Operand = (TypeSourceInfo*)nullptr;
}
bool isTypeOperand() const { return Operand.is<TypeSourceInfo *>(); }
@@ -737,8 +737,8 @@ public:
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
/// a single GUID.
- static UuidAttr *GetUuidAttrOfType(QualType QT,
- bool *HasMultipleGUIDsPtr = 0);
+ static const UuidAttr *GetUuidAttrOfType(QualType QT,
+ bool *HasMultipleGUIDsPtr = nullptr);
// Iterators
child_range children() {
@@ -832,7 +832,7 @@ public:
SourceLocation getLocStart() const LLVM_READONLY { return ThrowLoc; }
SourceLocation getLocEnd() const LLVM_READONLY {
- if (getSubExpr() == 0)
+ if (!getSubExpr())
return ThrowLoc;
return getSubExpr()->getLocEnd();
}
@@ -1031,7 +1031,7 @@ class CXXBindTemporaryExpr : public Expr {
public:
CXXBindTemporaryExpr(EmptyShell Empty)
- : Expr(CXXBindTemporaryExprClass, Empty), Temp(0), SubExpr(0) {}
+ : Expr(CXXBindTemporaryExprClass, Empty), Temp(nullptr), SubExpr(nullptr) {}
static CXXBindTemporaryExpr *Create(const ASTContext &C, CXXTemporary *Temp,
Expr* SubExpr);
@@ -1077,6 +1077,7 @@ private:
bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ListInitialization : 1;
+ bool StdInitListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@@ -1088,24 +1089,25 @@ protected:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
- : Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(false),
+ : Expr(SC, Empty), Constructor(nullptr), NumArgs(0), Elidable(false),
HadMultipleCandidates(false), ListInitialization(false),
- ZeroInitialization(false), ConstructKind(0), Args(0)
+ ZeroInitialization(false), ConstructKind(0), Args(nullptr)
{ }
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
- : Expr(CXXConstructExprClass, Empty), Constructor(0),
+ : Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
ListInitialization(false), ZeroInitialization(false),
- ConstructKind(0), Args(0)
+ ConstructKind(0), Args(nullptr)
{ }
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
@@ -1114,6 +1116,7 @@ public:
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
@@ -1137,6 +1140,13 @@ public:
bool isListInitialization() const { return ListInitialization; }
void setListInitialization(bool V) { ListInitialization = V; }
+ /// \brief Whether this constructor call was written as list-initialization,
+ /// but was interpreted as forming a std::initializer_list<T> from the list
+ /// and passing that as a single constructor argument.
+ /// See C++11 [over.match.list]p1 bullet 1.
+ bool isStdInitListInitialization() const { return StdInitListInitialization; }
+ void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
@@ -1161,7 +1171,10 @@ public:
const_arg_iterator arg_begin() const { return Args; }
const_arg_iterator arg_end() const { return Args + NumArgs; }
- Expr **getArgs() const { return reinterpret_cast<Expr **>(Args); }
+ Expr **getArgs() { return reinterpret_cast<Expr **>(Args); }
+ const Expr *const *getArgs() const {
+ return const_cast<CXXConstructExpr *>(this)->getArgs();
+ }
unsigned getNumArgs() const { return NumArgs; }
/// \brief Return the specified argument.
@@ -1269,6 +1282,7 @@ public:
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@@ -1307,18 +1321,6 @@ public:
/// includes an initializing expression (rather than capturing a variable),
/// and which can never occur implicitly.
class LambdaExpr : public Expr {
- enum {
- /// \brief Flag used by the Capture class to indicate that the given
- /// capture was implicit.
- Capture_Implicit = 0x01,
-
- /// \brief Flag used by the Capture class to indicate that the
- /// given capture was by-copy.
- ///
- /// This includes the case of a non-reference init-capture.
- Capture_ByCopy = 0x02
- };
-
/// \brief The source range that covers the lambda introducer ([...]).
SourceRange IntroducerRange;
@@ -1357,93 +1359,8 @@ class LambdaExpr : public Expr {
// expression, along with the index variables used to initialize by-copy
// array captures.
-public:
- /// \brief Describes the capture of a variable or of \c this, or of a
- /// C++1y init-capture.
- class Capture {
- llvm::PointerIntPair<Decl *, 2> DeclAndBits;
- SourceLocation Loc;
- SourceLocation EllipsisLoc;
-
- friend class ASTStmtReader;
- friend class ASTStmtWriter;
-
- public:
- /// \brief Create a new capture of a variable or of \c this.
- ///
- /// \param Loc The source location associated with this capture.
- ///
- /// \param Kind The kind of capture (this, byref, bycopy), which must
- /// not be init-capture.
- ///
- /// \param Implicit Whether the capture was implicit or explicit.
- ///
- /// \param Var The local variable being captured, or null if capturing
- /// \c this.
- ///
- /// \param EllipsisLoc The location of the ellipsis (...) for a
- /// capture that is a pack expansion, or an invalid source
- /// location to indicate that this is not a pack expansion.
- Capture(SourceLocation Loc, bool Implicit,
- LambdaCaptureKind Kind, VarDecl *Var = 0,
- SourceLocation EllipsisLoc = SourceLocation());
-
- /// \brief Determine the kind of capture.
- LambdaCaptureKind getCaptureKind() const;
-
- /// \brief Determine whether this capture handles the C++ \c this
- /// pointer.
- bool capturesThis() const { return DeclAndBits.getPointer() == 0; }
-
- /// \brief Determine whether this capture handles a variable.
- bool capturesVariable() const {
- return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this is an init-capture.
- bool isInitCapture() const {
- return capturesVariable() && getCapturedVar()->isInitCapture();
- }
-
- /// \brief Retrieve the declaration of the local variable being
- /// captured.
- ///
- /// This operation is only valid if this capture is a variable capture
- /// (other than a capture of \c this).
- VarDecl *getCapturedVar() const {
- assert(capturesVariable() && "No variable available for 'this' capture");
- return cast<VarDecl>(DeclAndBits.getPointer());
- }
-
- /// \brief Determine whether this was an implicit capture (not
- /// written between the square brackets introducing the lambda).
- bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
-
- /// \brief Determine whether this was an explicit capture (written
- /// between the square brackets introducing the lambda).
- bool isExplicit() const { return !isImplicit(); }
-
- /// \brief Retrieve the source location of the capture.
- ///
- /// For an explicit capture, this returns the location of the
- /// explicit capture in the source. For an implicit capture, this
- /// returns the location at which the variable or \c this was first
- /// used.
- SourceLocation getLocation() const { return Loc; }
-
- /// \brief Determine whether this capture is a pack expansion,
- /// which captures a function parameter pack.
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
-
- /// \brief Retrieve the location of the ellipsis for a capture
- /// that is a pack expansion.
- SourceLocation getEllipsisLoc() const {
- assert(isPackExpansion() && "No ellipsis location for a non-expansion");
- return EllipsisLoc;
- }
- };
+ typedef LambdaCapture Capture;
-private:
/// \brief Construct a lambda expression.
LambdaExpr(QualType T, SourceRange IntroducerRange,
LambdaCaptureDefault CaptureDefault,
@@ -1462,7 +1379,7 @@ private:
: Expr(LambdaExprClass, Empty),
NumCaptures(NumCaptures), CaptureDefault(LCD_None), ExplicitParams(false),
ExplicitResultType(false), HasArrayIndexVars(true) {
- getStoredStmts()[NumCaptures] = 0;
+ getStoredStmts()[NumCaptures] = nullptr;
}
Stmt **getStoredStmts() const {
@@ -1520,6 +1437,12 @@ public:
/// both implicit and explicit.
typedef const Capture *capture_iterator;
+ /// \brief An iterator over a range of lambda captures.
+ typedef llvm::iterator_range<capture_iterator> capture_range;
+
+ /// \brief Retrieve this lambda's captures.
+ capture_range captures() const;
+
/// \brief Retrieve an iterator pointing to the first lambda capture.
capture_iterator capture_begin() const;
@@ -1529,6 +1452,9 @@ public:
/// \brief Determine the number of captures in this lambda.
unsigned capture_size() const { return NumCaptures; }
+
+ /// \brief Retrieve this lambda's explicit captures.
+ capture_range explicit_captures() const;
/// \brief Retrieve an iterator pointing to the first explicit
/// lambda capture.
@@ -1538,6 +1464,9 @@ public:
/// explicit lambda captures.
capture_iterator explicit_capture_end() const;
+ /// \brief Retrieve this lambda's implicit captures.
+ capture_range implicit_captures() const;
+
/// \brief Retrieve an iterator pointing to the first implicit
/// lambda capture.
capture_iterator implicit_capture_begin() const;
@@ -1550,6 +1479,12 @@ public:
/// arguments.
typedef Expr **capture_init_iterator;
+ /// \brief Retrieve the initialization expressions for this lambda's captures.
+ llvm::iterator_range<capture_init_iterator> capture_inits() const {
+ return llvm::iterator_range<capture_init_iterator>(capture_init_begin(),
+ capture_init_end());
+ }
+
/// \brief Retrieve the first initialization argument for this
/// lambda expression (which initializes the first capture field).
capture_init_iterator capture_init_begin() const {
@@ -1717,7 +1652,7 @@ public:
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
SourceRange Range, SourceRange directInitRange);
explicit CXXNewExpr(EmptyShell Shell)
- : Expr(CXXNewExprClass, Shell), SubExprs(0) { }
+ : Expr(CXXNewExprClass, Shell), SubExprs(nullptr) { }
void AllocateArgsArray(const ASTContext &C, bool isArray,
unsigned numPlaceArgs, bool hasInitializer);
@@ -1751,10 +1686,10 @@ public:
bool isArray() const { return Array; }
Expr *getArraySize() {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
const Expr *getArraySize() const {
- return Array ? cast<Expr>(SubExprs[0]) : 0;
+ return Array ? cast<Expr>(SubExprs[0]) : nullptr;
}
unsigned getNumPlacementArgs() const { return NumPlacementArgs; }
@@ -1788,10 +1723,10 @@ public:
/// \brief The initializer of this new-expression.
Expr *getInitializer() {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
const Expr *getInitializer() const {
- return hasInitializer() ? cast<Expr>(SubExprs[Array]) : 0;
+ return hasInitializer() ? cast<Expr>(SubExprs[Array]) : nullptr;
}
/// \brief Returns the CXXConstructExpr from this new-expression, or null.
@@ -1885,7 +1820,8 @@ public:
ArrayForm(arrayForm), ArrayFormAsWritten(arrayFormAsWritten),
UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize) { }
explicit CXXDeleteExpr(EmptyShell Shell)
- : Expr(CXXDeleteExprClass, Shell), OperatorDelete(0), Argument(0) { }
+ : Expr(CXXDeleteExprClass, Shell), OperatorDelete(nullptr),
+ Argument(nullptr) {}
bool isGlobalDelete() const { return GlobalDelete; }
bool isArrayForm() const { return ArrayForm; }
@@ -2017,7 +1953,7 @@ public:
explicit CXXPseudoDestructorExpr(EmptyShell Shell)
: Expr(CXXPseudoDestructorExprClass, Shell),
- Base(0), IsArrow(false), QualifierLoc(), ScopeType(0) { }
+ Base(nullptr), IsArrow(false), QualifierLoc(), ScopeType(nullptr) { }
Expr *getBase() const { return cast<Expr>(Base); }
@@ -2110,138 +2046,12 @@ public:
child_range children() { return child_range(&Base, &Base + 1); }
};
-/// \brief Represents a GCC or MS unary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_pod(int) == true
-/// __is_enum(std::string) == false
-/// \endcode
-class UnaryTypeTraitExpr : public Expr {
- /// \brief The trait. A UnaryTypeTrait enum in MSVC compatible unsigned.
- unsigned UTT : 31;
- /// The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The type being queried.
- TypeSourceInfo *QueriedType;
-
-public:
- UnaryTypeTraitExpr(SourceLocation loc, UnaryTypeTrait utt,
- TypeSourceInfo *queried, bool value,
- SourceLocation rparen, QualType ty)
- : Expr(UnaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary,
- false, queried->getType()->isDependentType(),
- queried->getType()->isInstantiationDependentType(),
- queried->getType()->containsUnexpandedParameterPack()),
- UTT(utt), Value(value), Loc(loc), RParen(rparen), QueriedType(queried) { }
-
- explicit UnaryTypeTraitExpr(EmptyShell Empty)
- : Expr(UnaryTypeTraitExprClass, Empty), UTT(0), Value(false),
- QueriedType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- UnaryTypeTrait getTrait() const { return static_cast<UnaryTypeTrait>(UTT); }
-
- QualType getQueriedType() const { return QueriedType->getType(); }
-
- TypeSourceInfo *getQueriedTypeSourceInfo() const { return QueriedType; }
-
- bool getValue() const { return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == UnaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
-/// \brief Represents a GCC or MS binary type trait, as used in the
-/// implementation of TR1/C++11 type trait templates.
-///
-/// Example:
-/// \code
-/// __is_base_of(Base, Derived) == true
-/// \endcode
-class BinaryTypeTraitExpr : public Expr {
- /// \brief The trait. A BinaryTypeTrait enum in MSVC compatible unsigned.
- unsigned BTT : 8;
-
- /// The value of the type trait. Unspecified if dependent.
- bool Value : 1;
-
- /// \brief The location of the type trait keyword.
- SourceLocation Loc;
-
- /// \brief The location of the closing paren.
- SourceLocation RParen;
-
- /// \brief The lhs type being queried.
- TypeSourceInfo *LhsType;
-
- /// \brief The rhs type being queried.
- TypeSourceInfo *RhsType;
-
-public:
- BinaryTypeTraitExpr(SourceLocation loc, BinaryTypeTrait btt,
- TypeSourceInfo *lhsType, TypeSourceInfo *rhsType,
- bool value, SourceLocation rparen, QualType ty)
- : Expr(BinaryTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, false,
- lhsType->getType()->isDependentType() ||
- rhsType->getType()->isDependentType(),
- (lhsType->getType()->isInstantiationDependentType() ||
- rhsType->getType()->isInstantiationDependentType()),
- (lhsType->getType()->containsUnexpandedParameterPack() ||
- rhsType->getType()->containsUnexpandedParameterPack())),
- BTT(btt), Value(value), Loc(loc), RParen(rparen),
- LhsType(lhsType), RhsType(rhsType) { }
-
-
- explicit BinaryTypeTraitExpr(EmptyShell Empty)
- : Expr(BinaryTypeTraitExprClass, Empty), BTT(0), Value(false),
- LhsType(), RhsType() { }
-
- SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
- SourceLocation getLocEnd() const LLVM_READONLY { return RParen; }
-
- BinaryTypeTrait getTrait() const {
- return static_cast<BinaryTypeTrait>(BTT);
- }
-
- QualType getLhsType() const { return LhsType->getType(); }
- QualType getRhsType() const { return RhsType->getType(); }
-
- TypeSourceInfo *getLhsTypeSourceInfo() const { return LhsType; }
- TypeSourceInfo *getRhsTypeSourceInfo() const { return RhsType; }
-
- bool getValue() const { assert(!isTypeDependent()); return Value; }
-
- static bool classof(const Stmt *T) {
- return T->getStmtClass() == BinaryTypeTraitExprClass;
- }
-
- // Iterators
- child_range children() { return child_range(); }
-
- friend class ASTStmtReader;
-};
-
/// \brief A type trait used in the implementation of various C++11 and
/// Library TR1 trait templates.
///
/// \code
+/// __is_pod(int) == true
+/// __is_enum(std::string) == false
/// __is_trivially_constructible(vector<int>, int*, int*)
/// \endcode
class TypeTraitExpr : public Expr {
@@ -2334,7 +2144,7 @@ public:
friend class ASTStmtWriter;
};
-
+
/// \brief An Embarcadero array type trait, as used in the implementation of
/// __array_rank and __array_extent.
///
@@ -2504,7 +2314,7 @@ protected:
bool KnownContainsUnexpandedParameterPack);
OverloadExpr(StmtClass K, EmptyShell Empty)
- : Expr(K, Empty), QualifierLoc(), Results(0), NumResults(0),
+ : Expr(K, Empty), QualifierLoc(), Results(nullptr), NumResults(0),
HasTemplateKWAndArgsInfo(false) { }
void initializeResults(const ASTContext &C,
@@ -2554,6 +2364,9 @@ public:
decls_iterator decls_end() const {
return UnresolvedSetIterator(Results + NumResults);
}
+ llvm::iterator_range<decls_iterator> decls() const {
+ return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end());
+ }
/// \brief Gets the number of declarations in the unresolved set.
unsigned getNumDecls() const { return NumResults; }
@@ -2634,7 +2447,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2691,7 +2504,7 @@ class UnresolvedLookupExpr : public OverloadExpr {
UnresolvedLookupExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedLookupExprClass, Empty),
- RequiresADL(false), Overloaded(false), NamingClass(0)
+ RequiresADL(false), Overloaded(false), NamingClass(nullptr)
{}
friend class ASTStmtReader;
@@ -2706,7 +2519,7 @@ public:
UnresolvedSetIterator End) {
return new(C) UnresolvedLookupExpr(C, NamingClass, QualifierLoc,
SourceLocation(), NameInfo,
- ADL, Overloaded, 0, Begin, End);
+ ADL, Overloaded, nullptr, Begin, End);
}
static UnresolvedLookupExpr *Create(const ASTContext &C,
@@ -2781,7 +2594,7 @@ class DependentScopeDeclRefExpr : public Expr {
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -2875,7 +2688,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3151,7 +2964,7 @@ class CXXDependentScopeMemberExpr : public Expr {
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1);
}
/// \brief Return the optional template keyword and arguments info.
@@ -3296,7 +3109,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -3398,7 +3211,7 @@ class UnresolvedMemberExpr : public OverloadExpr {
UnresolvedMemberExpr(EmptyShell Empty)
: OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false),
- HasUnresolvedUsing(false), Base(0) { }
+ HasUnresolvedUsing(false), Base(nullptr) { }
friend class ASTStmtReader;
@@ -3612,7 +3425,7 @@ public:
};
inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() {
- if (!HasTemplateKWAndArgsInfo) return 0;
+ if (!HasTemplateKWAndArgsInfo) return nullptr;
if (isa<UnresolvedLookupExpr>(this))
return reinterpret_cast<ASTTemplateKWAndArgsInfo*>
(cast<UnresolvedLookupExpr>(this) + 1);
@@ -3904,39 +3717,51 @@ public:
/// temporary. When either happens, the expression will also track the
/// declaration which is responsible for the lifetime extension.
class MaterializeTemporaryExpr : public Expr {
-public:
- /// \brief The temporary-generating expression whose value will be
- /// materialized.
- Stmt *Temporary;
+private:
+ struct ExtraState {
+ /// \brief The temporary-generating expression whose value will be
+ /// materialized.
+ Stmt *Temporary;
- /// \brief The declaration which lifetime-extended this reference, if any.
- /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
- const ValueDecl *ExtendingDecl;
+ /// \brief The declaration which lifetime-extended this reference, if any.
+ /// Either a VarDecl, or (for a ctor-initializer) a FieldDecl.
+ const ValueDecl *ExtendingDecl;
+
+ unsigned ManglingNumber;
+ };
+ llvm::PointerUnion<Stmt *, ExtraState *> State;
friend class ASTStmtReader;
friend class ASTStmtWriter;
+ void initializeExtraState(const ValueDecl *ExtendedBy,
+ unsigned ManglingNumber);
+
public:
MaterializeTemporaryExpr(QualType T, Expr *Temporary,
- bool BoundToLvalueReference,
- const ValueDecl *ExtendedBy)
+ bool BoundToLvalueReference)
: Expr(MaterializeTemporaryExprClass, T,
BoundToLvalueReference? VK_LValue : VK_XValue, OK_Ordinary,
Temporary->isTypeDependent(), Temporary->isValueDependent(),
Temporary->isInstantiationDependent(),
Temporary->containsUnexpandedParameterPack()),
- Temporary(Temporary), ExtendingDecl(ExtendedBy) {
- }
+ State(Temporary) {}
MaterializeTemporaryExpr(EmptyShell Empty)
: Expr(MaterializeTemporaryExprClass, Empty) { }
+ Stmt *getTemporary() const {
+ return State.is<Stmt *>() ? State.get<Stmt *>()
+ : State.get<ExtraState *>()->Temporary;
+ }
+
/// \brief Retrieve the temporary-generating subexpression whose value will
/// be materialized into a glvalue.
- Expr *GetTemporaryExpr() const { return static_cast<Expr *>(Temporary); }
+ Expr *GetTemporaryExpr() const { return static_cast<Expr *>(getTemporary()); }
/// \brief Retrieve the storage duration for the materialized temporary.
StorageDuration getStorageDuration() const {
+ const ValueDecl *ExtendingDecl = getExtendingDecl();
if (!ExtendingDecl)
return SD_FullExpression;
// FIXME: This is not necessarily correct for a temporary materialized
@@ -3948,10 +3773,15 @@ public:
/// \brief Get the declaration which triggered the lifetime-extension of this
/// temporary, if any.
- const ValueDecl *getExtendingDecl() const { return ExtendingDecl; }
+ const ValueDecl *getExtendingDecl() const {
+ return State.is<Stmt *>() ? nullptr
+ : State.get<ExtraState *>()->ExtendingDecl;
+ }
+
+ void setExtendingDecl(const ValueDecl *ExtendedBy, unsigned ManglingNumber);
- void setExtendingDecl(const ValueDecl *ExtendedBy) {
- ExtendingDecl = ExtendedBy;
+ unsigned getManglingNumber() const {
+ return State.is<Stmt *>() ? 0 : State.get<ExtraState *>()->ManglingNumber;
}
/// \brief Determine whether this materialized temporary is bound to an
@@ -3961,10 +3791,10 @@ public:
}
SourceLocation getLocStart() const LLVM_READONLY {
- return Temporary->getLocStart();
+ return getTemporary()->getLocStart();
}
SourceLocation getLocEnd() const LLVM_READONLY {
- return Temporary->getLocEnd();
+ return getTemporary()->getLocEnd();
}
static bool classof(const Stmt *T) {
@@ -3972,7 +3802,13 @@ public:
}
// Iterators
- child_range children() { return child_range(&Temporary, &Temporary + 1); }
+ child_range children() {
+ if (State.is<Stmt *>())
+ return child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1);
+
+ auto ES = State.get<ExtraState *>();
+ return child_range(&ES->Temporary, &ES->Temporary + 1);
+ }
};
} // end namespace clang
diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h
index aeb55da1fb91..817c0cc43131 100644
--- a/include/clang/AST/ExprObjC.h
+++ b/include/clang/AST/ExprObjC.h
@@ -215,7 +215,7 @@ struct ObjCDictionaryElement {
} // end namespace clang
namespace llvm {
-template <> struct isPodLike<clang::ObjCDictionaryElement> : llvm::true_type {};
+template <> struct isPodLike<clang::ObjCDictionaryElement> : std::true_type {};
}
namespace clang {
@@ -277,14 +277,14 @@ class ObjCDictionaryLiteral : public Expr {
ExpansionData *getExpansionData() {
if (!HasPackExpansions)
- return 0;
+ return nullptr;
return reinterpret_cast<ExpansionData *>(getKeyValues() + NumElements);
}
const ExpansionData *getExpansionData() const {
if (!HasPackExpansions)
- return 0;
+ return nullptr;
return reinterpret_cast<const ExpansionData *>(getKeyValues()+NumElements);
}
@@ -683,13 +683,13 @@ public:
if (isExplicitProperty()) {
const ObjCPropertyDecl *PDecl = getExplicitProperty();
if (const ObjCMethodDecl *Getter = PDecl->getGetterMethodDecl())
- ResultType = Getter->getResultType();
+ ResultType = Getter->getReturnType();
else
ResultType = PDecl->getType();
} else {
const ObjCMethodDecl *Getter = getImplicitPropertyGetter();
if (Getter)
- ResultType = Getter->getResultType(); // with reference!
+ ResultType = Getter->getReturnType(); // with reference!
}
return ResultType;
}
@@ -743,7 +743,7 @@ private:
void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
PropertyOrGetter.setPointer(D);
PropertyOrGetter.setInt(false);
- SetterAndMethodRefFlags.setPointer(0);
+ SetterAndMethodRefFlags.setPointer(nullptr);
SetterAndMethodRefFlags.setInt(methRefFlags);
}
void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
@@ -1174,7 +1174,7 @@ public:
if (getReceiverKind() == Instance)
return static_cast<Expr *>(getReceiverPointer());
- return 0;
+ return nullptr;
}
const Expr *getInstanceReceiver() const {
return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
@@ -1201,7 +1201,7 @@ public:
TypeSourceInfo *getClassReceiverTypeInfo() const {
if (getReceiverKind() == Class)
return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
- return 0;
+ return nullptr;
}
void setClassReceiver(TypeSourceInfo *TSInfo) {
@@ -1270,14 +1270,14 @@ public:
if (HasMethod)
return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
- return 0;
+ return nullptr;
}
ObjCMethodDecl *getMethodDecl() {
if (HasMethod)
return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
- return 0;
+ return nullptr;
}
void setMethodDecl(ObjCMethodDecl *MD) {
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index b077426e6a47..1e8eff38d3ec 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -45,7 +45,7 @@ enum ExternalLoadResult {
/// no additional processing is required.
ELR_AlreadyLoaded
};
-
+
/// \brief Abstract interface for external sources of AST nodes.
///
/// External AST sources provide AST nodes constructed from some
@@ -53,7 +53,11 @@ enum ExternalLoadResult {
/// sources can resolve types and declarations from abstract IDs into
/// actual type and declaration nodes, and read parts of declaration
/// contexts.
-class ExternalASTSource {
+class ExternalASTSource : public RefCountedBase<ExternalASTSource> {
+ /// Generation number for this external AST source. Must be increased
+ /// whenever we might have added new redeclarations for existing decls.
+ uint32_t CurrentGeneration;
+
/// \brief Whether this AST source also provides information for
/// semantic analysis.
bool SemaSource;
@@ -61,7 +65,7 @@ class ExternalASTSource {
friend class ExternalSemaSource;
public:
- ExternalASTSource() : SemaSource(false) { }
+ ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { }
virtual ~ExternalASTSource();
@@ -79,6 +83,11 @@ public:
}
};
+ /// \brief Get the current generation of this AST source. This number
+ /// is incremented each time the AST source lazily extends an existing
+ /// entity.
+ uint32_t getGeneration() const { return CurrentGeneration; }
+
/// \brief Resolve a declaration ID into a declaration, potentially
/// building a new declaration.
///
@@ -138,7 +147,7 @@ public:
virtual void completeVisibleDeclsMap(const DeclContext *DC);
/// \brief Retrieve the module that corresponds to the given module ID.
- virtual Module *getModule(unsigned ID) { return 0; }
+ virtual Module *getModule(unsigned ID) { return nullptr; }
/// \brief Finds all declarations lexically contained within the given
/// DeclContext, after applying an optional filter predicate.
@@ -160,7 +169,7 @@ public:
/// \return true if an error occurred
ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC,
SmallVectorImpl<Decl*> &Result) {
- return FindExternalLexicalDecls(DC, 0, Result);
+ return FindExternalLexicalDecls(DC, nullptr, Result);
}
template <typename DeclTy>
@@ -171,43 +180,50 @@ public:
/// \brief Get the decls that are contained in a file in the Offset/Length
/// range. \p Length can be 0 to indicate a point at \p Offset instead of
- /// a range.
- virtual void FindFileRegionDecls(FileID File, unsigned Offset,unsigned Length,
- SmallVectorImpl<Decl *> &Decls) {}
+ /// a range.
+ virtual void FindFileRegionDecls(FileID File, unsigned Offset,
+ unsigned Length,
+ SmallVectorImpl<Decl *> &Decls);
+
+ /// \brief Gives the external AST source an opportunity to complete
+ /// the redeclaration chain for a declaration. Called each time we
+ /// need the most recent declaration of a declaration after the
+ /// generation count is incremented.
+ virtual void CompleteRedeclChain(const Decl *D);
/// \brief Gives the external AST source an opportunity to complete
/// an incomplete type.
- virtual void CompleteType(TagDecl *Tag) {}
+ virtual void CompleteType(TagDecl *Tag);
/// \brief Gives the external AST source an opportunity to complete an
/// incomplete Objective-C class.
///
/// This routine will only be invoked if the "externally completed" bit is
- /// set on the ObjCInterfaceDecl via the function
+ /// set on the ObjCInterfaceDecl via the function
/// \c ObjCInterfaceDecl::setExternallyCompleted().
- virtual void CompleteType(ObjCInterfaceDecl *Class) { }
+ virtual void CompleteType(ObjCInterfaceDecl *Class);
/// \brief Loads comment ranges.
- virtual void ReadComments() { }
+ virtual void ReadComments();
/// \brief Notify ExternalASTSource that we started deserialization of
/// a decl or type so until FinishedDeserializing is called there may be
/// decls that are initializing. Must be paired with FinishedDeserializing.
///
/// The default implementation of this method is a no-op.
- virtual void StartedDeserializing() { }
+ virtual void StartedDeserializing();
/// \brief Notify ExternalASTSource that we finished the deserialization of
/// a decl or type. Must be paired with StartedDeserializing.
///
/// The default implementation of this method is a no-op.
- virtual void FinishedDeserializing() { }
+ virtual void FinishedDeserializing();
/// \brief Function that will be invoked when we begin parsing a new
/// translation unit involving this external AST source.
///
/// The default implementation of this method is a no-op.
- virtual void StartTranslationUnit(ASTConsumer *Consumer) { }
+ virtual void StartTranslationUnit(ASTConsumer *Consumer);
/// \brief Print any statistics that have been gathered regarding
/// the external AST source.
@@ -243,16 +259,12 @@ public:
/// out according to the ABI.
///
/// \returns true if the record layout was provided, false otherwise.
- virtual bool
- layoutRecordType(const RecordDecl *Record,
- uint64_t &Size, uint64_t &Alignment,
- llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
- llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets)
- {
- return false;
- }
-
+ virtual bool layoutRecordType(
+ const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets,
+ llvm::DenseMap<const CXXRecordDecl *, CharUnits> &VirtualBaseOffsets);
+
//===--------------------------------------------------------------------===//
// Queries for performance analysis.
//===--------------------------------------------------------------------===//
@@ -284,6 +296,9 @@ protected:
static DeclContextLookupResult
SetNoExternalVisibleDeclsForName(const DeclContext *DC,
DeclarationName Name);
+
+ /// \brief Increment the current generation.
+ uint32_t incrementGeneration(ASTContext &C);
};
/// \brief A lazy pointer to an AST node (of base type T) that resides
@@ -354,6 +369,100 @@ public:
}
};
+/// \brief A lazy value (of type T) that is within an AST node of type Owner,
+/// where the value might change in later generations of the external AST
+/// source.
+template<typename Owner, typename T, void (ExternalASTSource::*Update)(Owner)>
+struct LazyGenerationalUpdatePtr {
+ /// A cache of the value of this pointer, in the most recent generation in
+ /// which we queried it.
+ struct LazyData {
+ LazyData(ExternalASTSource *Source, T Value)
+ : ExternalSource(Source), LastGeneration(0), LastValue(Value) {}
+ ExternalASTSource *ExternalSource;
+ uint32_t LastGeneration;
+ T LastValue;
+ };
+
+ // Our value is represented as simply T if there is no external AST source.
+ typedef llvm::PointerUnion<T, LazyData*> ValueType;
+ ValueType Value;
+
+ LazyGenerationalUpdatePtr(ValueType V) : Value(V) {}
+
+ // Defined in ASTContext.h
+ static ValueType makeValue(const ASTContext &Ctx, T Value);
+
+public:
+ explicit LazyGenerationalUpdatePtr(const ASTContext &Ctx, T Value = T())
+ : Value(makeValue(Ctx, Value)) {}
+
+ /// Create a pointer that is not potentially updated by later generations of
+ /// the external AST source.
+ enum NotUpdatedTag { NotUpdated };
+ LazyGenerationalUpdatePtr(NotUpdatedTag, T Value = T())
+ : Value(Value) {}
+
+ /// Forcibly set this pointer (which must be lazy) as needing updates.
+ void markIncomplete() {
+ Value.template get<LazyData *>()->LastGeneration = 0;
+ }
+
+ /// Set the value of this pointer, in the current generation.
+ void set(T NewValue) {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ LazyVal->LastValue = NewValue;
+ return;
+ }
+ Value = NewValue;
+ }
+
+ /// Set the value of this pointer, for this and all future generations.
+ void setNotUpdated(T NewValue) { Value = NewValue; }
+
+ /// Get the value of this pointer, updating its owner if necessary.
+ T get(Owner O) {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>()) {
+ if (LazyVal->LastGeneration != LazyVal->ExternalSource->getGeneration()) {
+ LazyVal->LastGeneration = LazyVal->ExternalSource->getGeneration();
+ (LazyVal->ExternalSource->*Update)(O);
+ }
+ return LazyVal->LastValue;
+ }
+ return Value.template get<T>();
+ }
+
+ /// Get the most recently computed value of this pointer without updating it.
+ T getNotUpdated() const {
+ if (LazyData *LazyVal = Value.template dyn_cast<LazyData*>())
+ return LazyVal->LastValue;
+ return Value.template get<T>();
+ }
+
+ void *getOpaqueValue() { return Value.getOpaqueValue(); }
+ static LazyGenerationalUpdatePtr getFromOpaqueValue(void *Ptr) {
+ return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr));
+ }
+};
+} // end namespace clang
+
+/// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be
+/// placed into a PointerUnion.
+namespace llvm {
+template<typename Owner, typename T,
+ void (clang::ExternalASTSource::*Update)(Owner)>
+struct PointerLikeTypeTraits<
+ clang::LazyGenerationalUpdatePtr<Owner, T, Update>> {
+ typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr;
+ static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); }
+ static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); }
+ enum {
+ NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1
+ };
+};
+}
+
+namespace clang {
/// \brief Represents a lazily-loaded vector of data.
///
/// The lazily-loaded vector of data contains data that is partially loaded
@@ -519,7 +628,7 @@ public:
if (From.Position < 0) {
Loaded.erase(Loaded.end() + From.Position, Loaded.end());
- From = begin(0, true);
+ From = begin(nullptr, true);
}
Local.erase(Local.begin() + From.Position, Local.begin() + To.Position);
diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h
new file mode 100644
index 000000000000..8633c9796523
--- /dev/null
+++ b/include/clang/AST/LambdaCapture.h
@@ -0,0 +1,123 @@
+//===--- LambdaCapture.h - Types for C++ Lambda Captures --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines the LambdaCapture class.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_LAMBDACAPTURE_H
+#define LLVM_CLANG_AST_LAMBDACAPTURE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Lambda.h"
+#include "llvm/ADT/PointerIntPair.h"
+
+namespace clang {
+
+/// \brief Describes the capture of a variable or of \c this, or of a
+/// C++1y init-capture.
+class LambdaCapture {
+ enum {
+ /// \brief Flag used by the Capture class to indicate that the given
+ /// capture was implicit.
+ Capture_Implicit = 0x01,
+
+ /// \brief Flag used by the Capture class to indicate that the
+ /// given capture was by-copy.
+ ///
+ /// This includes the case of a non-reference init-capture.
+ Capture_ByCopy = 0x02
+ };
+
+ llvm::PointerIntPair<Decl *, 2> DeclAndBits;
+ SourceLocation Loc;
+ SourceLocation EllipsisLoc;
+
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+
+public:
+ /// \brief Create a new capture of a variable or of \c this.
+ ///
+ /// \param Loc The source location associated with this capture.
+ ///
+ /// \param Kind The kind of capture (this, byref, bycopy), which must
+ /// not be init-capture.
+ ///
+ /// \param Implicit Whether the capture was implicit or explicit.
+ ///
+ /// \param Var The local variable being captured, or null if capturing
+ /// \c this.
+ ///
+ /// \param EllipsisLoc The location of the ellipsis (...) for a
+ /// capture that is a pack expansion, or an invalid source
+ /// location to indicate that this is not a pack expansion.
+ LambdaCapture(SourceLocation Loc, bool Implicit, LambdaCaptureKind Kind,
+ VarDecl *Var = nullptr,
+ SourceLocation EllipsisLoc = SourceLocation());
+
+ /// \brief Determine the kind of capture.
+ LambdaCaptureKind getCaptureKind() const;
+
+ /// \brief Determine whether this capture handles the C++ \c this
+ /// pointer.
+ bool capturesThis() const { return DeclAndBits.getPointer() == nullptr; }
+
+ /// \brief Determine whether this capture handles a variable.
+ bool capturesVariable() const {
+ return dyn_cast_or_null<VarDecl>(DeclAndBits.getPointer());
+ }
+
+ /// \brief Determine whether this is an init-capture.
+ bool isInitCapture() const {
+ return capturesVariable() && getCapturedVar()->isInitCapture();
+ }
+
+ /// \brief Retrieve the declaration of the local variable being
+ /// captured.
+ ///
+ /// This operation is only valid if this capture is a variable capture
+ /// (other than a capture of \c this).
+ VarDecl *getCapturedVar() const {
+ assert(capturesVariable() && "No variable available for 'this' capture");
+ return cast<VarDecl>(DeclAndBits.getPointer());
+ }
+
+ /// \brief Determine whether this was an implicit capture (not
+ /// written between the square brackets introducing the lambda).
+ bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; }
+
+ /// \brief Determine whether this was an explicit capture (written
+ /// between the square brackets introducing the lambda).
+ bool isExplicit() const { return !isImplicit(); }
+
+ /// \brief Retrieve the source location of the capture.
+ ///
+ /// For an explicit capture, this returns the location of the
+ /// explicit capture in the source. For an implicit capture, this
+ /// returns the location at which the variable or \c this was first
+ /// used.
+ SourceLocation getLocation() const { return Loc; }
+
+ /// \brief Determine whether this capture is a pack expansion,
+ /// which captures a function parameter pack.
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+ /// \brief Retrieve the location of the ellipsis for a capture
+ /// that is a pack expansion.
+ SourceLocation getEllipsisLoc() const {
+ assert(isPackExpansion() && "No ellipsis location for a non-expansion");
+ return EllipsisLoc;
+ }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_LAMBDACAPTURE_H
diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile
index ae84bcfd5817..85e6449c509a 100644
--- a/include/clang/AST/Makefile
+++ b/include/clang/AST/Makefile
@@ -1,6 +1,6 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc \
+BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \
StmtNodes.inc DeclNodes.inc \
CommentNodes.inc CommentHTMLTags.inc \
CommentHTMLTagsProperties.inc \
@@ -30,6 +30,12 @@ $(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
$(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute AST visitor with tblgen"
+ $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h
index c4d0d22cdf0a..a8d119971b33 100644
--- a/include/clang/AST/Mangle.h
+++ b/include/clang/AST/Mangle.h
@@ -31,36 +31,10 @@ namespace clang {
class FunctionDecl;
class NamedDecl;
class ObjCMethodDecl;
- class VarDecl;
+ class StringLiteral;
struct ThisAdjustment;
struct ThunkInfo;
-
-/// MangleBuffer - a convenient class for storing a name which is
-/// either the result of a mangling or is a constant string with
-/// external memory ownership.
-class MangleBuffer {
-public:
- void setString(StringRef Ref) {
- String = Ref;
- }
-
- SmallVectorImpl<char> &getBuffer() {
- return Buffer;
- }
-
- StringRef getString() const {
- if (!String.empty()) return String;
- return Buffer.str();
- }
-
- operator StringRef() const {
- return getString();
- }
-
-private:
- StringRef String;
- SmallString<256> Buffer;
-};
+ class VarDecl;
/// MangleContext - Context for tracking state which persists across multiple
/// calls to the C++ name mangler.
@@ -80,6 +54,7 @@ private:
llvm::DenseMap<const BlockDecl*, unsigned> GlobalBlockIds;
llvm::DenseMap<const BlockDecl*, unsigned> LocalBlockIds;
+ llvm::DenseMap<const TagDecl*, uint64_t> AnonStructIds;
public:
ManglerKind getKind() const { return Kind; }
@@ -104,12 +79,19 @@ public:
Result = BlockIds.insert(std::make_pair(BD, BlockIds.size()));
return Result.first->second;
}
-
+
+ uint64_t getAnonymousStructId(const TagDecl *TD) {
+ std::pair<llvm::DenseMap<const TagDecl *, uint64_t>::iterator, bool>
+ Result = AnonStructIds.insert(std::make_pair(TD, AnonStructIds.size()));
+ return Result.first->second;
+ }
+
/// @name Mangler Entry Points
/// @{
bool shouldMangleDeclName(const NamedDecl *D);
virtual bool shouldMangleCXXName(const NamedDecl *D) = 0;
+ virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0;
// FIXME: consider replacing raw_ostream & with something like SmallString &.
void mangleName(const NamedDecl *D, raw_ostream &);
@@ -121,6 +103,7 @@ public:
const ThisAdjustment &ThisAdjustment,
raw_ostream &) = 0;
virtual void mangleReferenceTemporary(const VarDecl *D,
+ unsigned ManglingNumber,
raw_ostream &) = 0;
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
@@ -128,6 +111,7 @@ public:
raw_ostream &) = 0;
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
raw_ostream &) = 0;
+ virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
void mangleGlobalBlock(const BlockDecl *BD,
const NamedDecl *ID,
@@ -200,9 +184,23 @@ public:
raw_ostream &Out) = 0;
virtual void mangleVirtualMemPtrThunk(const CXXMethodDecl *MD,
- uint64_t OffsetInVFTable,
raw_ostream &) = 0;
+ virtual void mangleCXXRTTIBaseClassDescriptor(
+ const CXXRecordDecl *Derived, uint32_t NVOffset, int32_t VBPtrOffset,
+ uint32_t VBTableOffset, uint32_t Flags, raw_ostream &Out) = 0;
+
+ virtual void mangleCXXRTTIBaseClassArray(const CXXRecordDecl *Derived,
+ raw_ostream &Out) = 0;
+ virtual void
+ mangleCXXRTTIClassHierarchyDescriptor(const CXXRecordDecl *Derived,
+ raw_ostream &Out) = 0;
+
+ virtual void
+ mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
+ ArrayRef<const CXXRecordDecl *> BasePath,
+ raw_ostream &Out) = 0;
+
static bool classof(const MangleContext *C) {
return C->getKind() == MK_Microsoft;
}
diff --git a/include/clang/AST/MangleNumberingContext.h b/include/clang/AST/MangleNumberingContext.h
index 5a227f201fbb..56c995264b32 100644
--- a/include/clang/AST/MangleNumberingContext.h
+++ b/include/clang/AST/MangleNumberingContext.h
@@ -33,7 +33,6 @@ class VarDecl;
class MangleNumberingContext
: public RefCountedBase<MangleNumberingContext> {
llvm::DenseMap<const Type *, unsigned> ManglingNumbers;
- llvm::DenseMap<IdentifierInfo*, unsigned> TagManglingNumbers;
public:
virtual ~MangleNumberingContext() {}
@@ -46,13 +45,18 @@ public:
/// context.
unsigned getManglingNumber(const BlockDecl *BD);
+ /// Static locals are numbered by source order.
+ unsigned getStaticLocalNumber(const VarDecl *VD);
+
/// \brief Retrieve the mangling number of a static local variable within
/// this context.
- virtual unsigned getManglingNumber(const VarDecl *VD) = 0;
+ virtual unsigned getManglingNumber(const VarDecl *VD,
+ unsigned MSLocalManglingNumber) = 0;
/// \brief Retrieve the mangling number of a static local variable within
/// this context.
- unsigned getManglingNumber(const TagDecl *TD);
+ virtual unsigned getManglingNumber(const TagDecl *TD,
+ unsigned MSLocalManglingNumber) = 0;
};
} // end namespace clang
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index b332b153fe8d..fc719bdc16c3 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -88,7 +88,8 @@ public:
private:
/// \brief Builds the global specifier.
- NestedNameSpecifier() : Prefix(0, StoredIdentifier), Specifier(0) { }
+ NestedNameSpecifier()
+ : Prefix(nullptr, StoredIdentifier), Specifier(nullptr) {}
/// \brief Copy constructor used internally to clone nested name
/// specifiers.
@@ -160,7 +161,7 @@ public:
if (Prefix.getInt() == StoredIdentifier)
return (IdentifierInfo *)Specifier;
- return 0;
+ return nullptr;
}
/// \brief Retrieve the namespace stored in this nested name
@@ -177,7 +178,7 @@ public:
Prefix.getInt() == StoredTypeSpecWithTemplate)
return (const Type *)Specifier;
- return 0;
+ return nullptr;
}
/// \brief Whether this nested name specifier refers to a dependent
@@ -222,7 +223,7 @@ class NestedNameSpecifierLoc {
public:
/// \brief Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() : Qualifier(0), Data(0) { }
+ NestedNameSpecifierLoc() : Qualifier(nullptr), Data(nullptr) { }
/// \brief Construct a nested-name-specifier with source location information
/// from
@@ -344,7 +345,8 @@ class NestedNameSpecifierLocBuilder {
public:
NestedNameSpecifierLocBuilder()
- : Representation(0), Buffer(0), BufferSize(0), BufferCapacity(0) { }
+ : Representation(nullptr), Buffer(nullptr), BufferSize(0),
+ BufferCapacity(0) {}
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
@@ -457,7 +459,7 @@ public:
/// \brief Clear out this builder, and prepare it to build another
/// nested-name-specifier with source-location information.
void Clear() {
- Representation = 0;
+ Representation = nullptr;
BufferSize = 0;
}
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
new file mode 100644
index 000000000000..3345959653a6
--- /dev/null
+++ b/include/clang/AST/OpenMPClause.h
@@ -0,0 +1,1455 @@
+//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file defines OpenMP AST classes for clauses.
+/// There are clauses for executable directives, clauses for declarative
+/// directives and clauses which can be used in both kinds of directives.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
+#define LLVM_CLANG_AST_OPENMPCLAUSE_H
+
+#include "clang/AST/Expr.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+//===----------------------------------------------------------------------===//
+// AST classes for clauses.
+//===----------------------------------------------------------------------===//
+
+/// \brief This is a basic class for representing single OpenMP clause.
+///
+class OMPClause {
+ /// \brief Starting location of the clause (the clause keyword).
+ SourceLocation StartLoc;
+ /// \brief Ending location of the clause.
+ SourceLocation EndLoc;
+ /// \brief Kind of the clause.
+ OpenMPClauseKind Kind;
+
+protected:
+ OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
+ : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
+
+public:
+ /// \brief Returns the starting location of the clause.
+ SourceLocation getLocStart() const { return StartLoc; }
+ /// \brief Returns the ending location of the clause.
+ SourceLocation getLocEnd() const { return EndLoc; }
+
+ /// \brief Sets the starting location of the clause.
+ void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
+ /// \brief Sets the ending location of the clause.
+ void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
+
+ /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
+ OpenMPClauseKind getClauseKind() const { return Kind; }
+
+ bool isImplicit() const { return StartLoc.isInvalid(); }
+
+ StmtRange children();
+ ConstStmtRange children() const {
+ return const_cast<OMPClause *>(this)->children();
+ }
+ static bool classof(const OMPClause *T) { return true; }
+};
+
+/// \brief This represents clauses with the list of variables like 'private',
+/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
+/// '#pragma omp ...' directives.
+template <class T> class OMPVarListClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Number of variables in the list.
+ unsigned NumVars;
+
+protected:
+ /// \brief Fetches list of variables associated with this clause.
+ MutableArrayRef<Expr *> getVarRefs() {
+ return MutableArrayRef<Expr *>(
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ NumVars);
+ }
+
+ /// \brief Sets the list of variables for this clause.
+ void setVarRefs(ArrayRef<Expr *> VL) {
+ assert(VL.size() == NumVars &&
+ "Number of variables is not the same as the preallocated buffer");
+ std::copy(
+ VL.begin(), VL.end(),
+ reinterpret_cast<Expr **>(
+ reinterpret_cast<char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
+ }
+
+ /// \brief Build a clause with \a N variables
+ ///
+ /// \param K Kind of the clause.
+ /// \param StartLoc Starting location of the clause (the clause keyword).
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
+ : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}
+
+public:
+ typedef MutableArrayRef<Expr *>::iterator varlist_iterator;
+ typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
+ typedef llvm::iterator_range<varlist_iterator> varlist_range;
+ typedef llvm::iterator_range<varlist_const_iterator> varlist_const_range;
+
+ unsigned varlist_size() const { return NumVars; }
+ bool varlist_empty() const { return NumVars == 0; }
+
+ varlist_range varlists() {
+ return varlist_range(varlist_begin(), varlist_end());
+ }
+ varlist_const_range varlists() const {
+ return varlist_const_range(varlist_begin(), varlist_end());
+ }
+
+ varlist_iterator varlist_begin() { return getVarRefs().begin(); }
+ varlist_iterator varlist_end() { return getVarRefs().end(); }
+ varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
+ varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Fetches list of all variables in the clause.
+ ArrayRef<const Expr *> getVarRefs() const {
+ return ArrayRef<const Expr *>(
+ reinterpret_cast<const Expr *const *>(
+ reinterpret_cast<const char *>(this) +
+ llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
+ NumVars);
+ }
+};
+
+/// \brief This represents 'if' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel if(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'if'
+/// clause with condition 'a > 5'.
+///
+class OMPIfClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'if' clause.
+ Stmt *Condition;
+
+ /// \brief Set condition.
+ ///
+ void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+ /// \brief Build 'if' clause with condition \a Cond.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Cond Condition of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Condition(Cond) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPIfClause()
+ : OMPClause(OMPC_if, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns condition.
+ Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_if;
+ }
+
+ StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'final' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task final(a > 5)
+/// \endcode
+/// In this example directive '#pragma omp task' has simple 'final'
+/// clause with condition 'a > 5'.
+///
+class OMPFinalClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'if' clause.
+ Stmt *Condition;
+
+ /// \brief Set condition.
+ ///
+ void setCondition(Expr *Cond) { Condition = Cond; }
+
+public:
+ /// \brief Build 'final' clause with condition \a Cond.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param Cond Condition of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPFinalClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_final, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Condition(Cond) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPFinalClause()
+ : OMPClause(OMPC_final, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Condition(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns condition.
+ Expr *getCondition() const { return cast_or_null<Expr>(Condition); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_final;
+ }
+
+ StmtRange children() { return StmtRange(&Condition, &Condition + 1); }
+};
+
+/// \brief This represents 'num_threads' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel num_threads(6)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'num_threads'
+/// clause with number of threads '6'.
+///
+class OMPNumThreadsClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Condition of the 'num_threads' clause.
+ Stmt *NumThreads;
+
+ /// \brief Set condition.
+ ///
+ void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }
+
+public:
+ /// \brief Build 'num_threads' clause with condition \a NumThreads.
+ ///
+ /// \param NumThreads Number of threads for the construct.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ NumThreads(NumThreads) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPNumThreadsClause()
+ : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), NumThreads(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns number of threads.
+ Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_num_threads;
+ }
+
+ StmtRange children() { return StmtRange(&NumThreads, &NumThreads + 1); }
+};
+
+/// \brief This represents 'safelen' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd safelen(4)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'safelen'
+/// with single expression '4'.
+/// If the safelen clause is used then no two iterations executed
+/// concurrently with SIMD instructions can have a greater distance
+/// in the logical iteration space than its value. The parameter of
+/// the safelen clause must be a constant positive integer expression.
+///
+class OMPSafelenClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Safe iteration space distance.
+ Stmt *Safelen;
+
+ /// \brief Set safelen.
+ void setSafelen(Expr *Len) { Safelen = Len; }
+
+public:
+ /// \brief Build 'safelen' clause.
+ ///
+ /// \param Len Expression associated with this clause.
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Safelen(Len) {}
+
+ /// \brief Build an empty clause.
+ ///
+ explicit OMPSafelenClause()
+ : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Safelen(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Return safe iteration space distance.
+ Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_safelen;
+ }
+
+ StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); }
+};
+
+/// \brief This represents 'collapse' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp simd collapse(3)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'collapse'
+/// with single expression '3'.
+/// The parameter must be a constant positive integer expression, it specifies
+/// the number of nested loops that should be collapsed into a single iteration
+/// space.
+///
+class OMPCollapseClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief Number of for-loops.
+ Stmt *NumForLoops;
+
+ /// \brief Set the number of associated for-loops.
+ void setNumForLoops(Expr *Num) { NumForLoops = Num; }
+
+public:
+ /// \brief Build 'collapse' clause.
+ ///
+ /// \param Num Expression associated with this clause.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ NumForLoops(Num) {}
+
+ /// \brief Build an empty clause.
+ ///
+ explicit OMPCollapseClause()
+ : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), NumForLoops(nullptr) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Return the number of associated for-loops.
+ Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_collapse;
+ }
+
+ StmtRange children() { return StmtRange(&NumForLoops, &NumForLoops + 1); }
+};
+
+/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp parallel default(shared)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'default'
+/// clause with kind 'shared'.
+///
+class OMPDefaultClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief A kind of the 'default' clause.
+ OpenMPDefaultClauseKind Kind;
+ /// \brief Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// \brief Set kind of the clauses.
+ ///
+ /// \param K Argument of clause.
+ ///
+ void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
+
+ /// \brief Set argument location.
+ ///
+ /// \param KLoc Argument location.
+ ///
+ void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+ /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
+ ///
+ /// \param A Argument of the clause ('none' or 'shared').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPDefaultClause()
+ : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
+ KindKwLoc(SourceLocation()) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns kind of the clause.
+ OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
+
+ /// \brief Returns location of clause kind.
+ SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_default;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'proc_bind' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp parallel proc_bind(master)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
+/// clause with kind 'master'.
+///
+class OMPProcBindClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief A kind of the 'proc_bind' clause.
+ OpenMPProcBindClauseKind Kind;
+ /// \brief Start location of the kind in source code.
+ SourceLocation KindKwLoc;
+
+ /// \brief Set kind of the clause.
+ ///
+ /// \param K Kind of clause.
+ ///
+ void setProcBindKind(OpenMPProcBindClauseKind K) { Kind = K; }
+
+ /// \brief Set clause kind location.
+ ///
+ /// \param KLoc Kind location.
+ ///
+ void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
+
+public:
+ /// \brief Build 'proc_bind' clause with argument \a A ('master', 'close' or
+ /// 'spread').
+ ///
+ /// \param A Argument of the clause ('master', 'close' or 'spread').
+ /// \param ALoc Starting location of the argument.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPProcBindClause(OpenMPProcBindClauseKind A, SourceLocation ALoc,
+ SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc)
+ : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(A), KindKwLoc(ALoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPProcBindClause()
+ : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()),
+ LParenLoc(SourceLocation()), Kind(OMPC_PROC_BIND_unknown),
+ KindKwLoc(SourceLocation()) {}
+
+ /// \brief Sets the location of '('.
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getLParenLoc() const { return LParenLoc; }
+
+ /// \brief Returns kind of the clause.
+ OpenMPProcBindClauseKind getProcBindKind() const { return Kind; }
+
+ /// \brief Returns location of clause kind.
+ SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_proc_bind;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'schedule' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for schedule(static, 3)
+/// \endcode
+/// In this example directive '#pragma omp for' has 'schedule' clause with
+/// arguments 'static' and '3'.
+///
+class OMPScheduleClause : public OMPClause {
+ friend class OMPClauseReader;
+ /// \brief Location of '('.
+ SourceLocation LParenLoc;
+ /// \brief A kind of the 'schedule' clause.
+ OpenMPScheduleClauseKind Kind;
+ /// \brief Start location of the schedule ind in source code.
+ SourceLocation KindLoc;
+ /// \brief Location of ',' (if any).
+ SourceLocation CommaLoc;
+ /// \brief Chunk size.
+ Stmt *ChunkSize;
+
+ /// \brief Set schedule kind.
+ ///
+ /// \param K Schedule kind.
+ ///
+ void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }
+ /// \brief Sets the location of '('.
+ ///
+ /// \param Loc Location of '('.
+ ///
+ void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+ /// \brief Set schedule kind start location.
+ ///
+ /// \param KLoc Schedule kind location.
+ ///
+ void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }
+ /// \brief Set location of ','.
+ ///
+ /// \param Loc Location of ','.
+ ///
+ void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }
+ /// \brief Set chunk size.
+ ///
+ /// \param E Chunk size.
+ ///
+ void setChunkSize(Expr *E) { ChunkSize = E; }
+
+public:
+ /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size
+ /// expression \a ChunkSize.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param KLoc Starting location of the argument.
+ /// \param CommaLoc Location of ','.
+ /// \param EndLoc Ending location of the clause.
+ /// \param Kind Schedule kind.
+ /// \param ChunkSize Chunk size.
+ ///
+ OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation KLoc, SourceLocation CommaLoc,
+ SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
+ Expr *ChunkSize)
+ : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc),
+ Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {}
+
+ /// \brief Build an empty clause.
+ ///
+ explicit OMPScheduleClause()
+ : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()),
+ Kind(OMPC_SCHEDULE_unknown), ChunkSize(nullptr) {}
+
+ /// \brief Get kind of the clause.
+ ///
+ OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }
+ /// \brief Get location of '('.
+ ///
+ SourceLocation getLParenLoc() { return LParenLoc; }
+ /// \brief Get kind location.
+ ///
+ SourceLocation getScheduleKindLoc() { return KindLoc; }
+ /// \brief Get location of ','.
+ ///
+ SourceLocation getCommaLoc() { return CommaLoc; }
+ /// \brief Get chunk size.
+ ///
+ Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSize); }
+ /// \brief Get chunk size.
+ ///
+ Expr *getChunkSize() const { return dyn_cast_or_null<Expr>(ChunkSize); }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_schedule;
+ }
+
+ StmtRange children() { return StmtRange(&ChunkSize, &ChunkSize + 1); }
+};
+
+/// \brief This represents 'ordered' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for ordered
+/// \endcode
+/// In this example directive '#pragma omp for' has 'ordered' clause.
+///
+class OMPOrderedClause : public OMPClause {
+public:
+ /// \brief Build 'ordered' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_ordered, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPOrderedClause()
+ : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_ordered;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'nowait' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp for nowait
+/// \endcode
+/// In this example directive '#pragma omp for' has 'nowait' clause.
+///
+class OMPNowaitClause : public OMPClause {
+public:
+ /// \brief Build 'nowait' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_nowait, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPNowaitClause()
+ : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_nowait;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'untied' clause in the '#pragma omp ...' directive.
+///
+/// \code
+/// #pragma omp task untied
+/// \endcode
+/// In this example directive '#pragma omp task' has 'untied' clause.
+///
+class OMPUntiedClause : public OMPClause {
+public:
+ /// \brief Build 'untied' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_untied, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPUntiedClause()
+ : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_untied;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents 'mergeable' clause in the '#pragma omp ...'
+/// directive.
+///
+/// \code
+/// #pragma omp task mergeable
+/// \endcode
+/// In this example directive '#pragma omp task' has 'mergeable' clause.
+///
+class OMPMergeableClause : public OMPClause {
+public:
+ /// \brief Build 'mergeable' clause.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param EndLoc Ending location of the clause.
+ ///
+ OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
+ : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ OMPMergeableClause()
+ : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {}
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_mergeable;
+ }
+
+ StmtRange children() { return StmtRange(); }
+};
+
+/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel private(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'private'
+/// with the variables 'a' and 'b'.
+///
+class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPPrivateClause(unsigned N)
+ : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_private;
+ }
+};
+
+/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel firstprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPFirstprivateClause(unsigned N)
+ : OMPVarListClause<OMPFirstprivateClause>(
+ OMPC_firstprivate, SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPFirstprivateClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_firstprivate;
+ }
+};
+
+/// \brief This represents clause 'lastprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd lastprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'lastprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPLastprivateClause(unsigned N)
+ : OMPVarListClause<OMPLastprivateClause>(
+ OMPC_lastprivate, SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPLastprivateClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_lastprivate;
+ }
+};
+
+/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel shared(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'shared'
+/// with the variables 'a' and 'b'.
+///
+class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPSharedClause(unsigned N)
+ : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_shared;
+ }
+};
+
+/// \brief This represents clause 'reduction' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp parallel reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'reduction'
+/// with operator '+' and the variables 'a' and 'b'.
+///
+class OMPReductionClause : public OMPVarListClause<OMPReductionClause> {
+ friend class OMPClauseReader;
+ /// \brief Location of ':'.
+ SourceLocation ColonLoc;
+ /// \brief Nested name specifier for C++.
+ NestedNameSpecifierLoc QualifierLoc;
+ /// \brief Name of custom operator.
+ DeclarationNameInfo NameInfo;
+
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param ColonLoc Location of ':'.
+ /// \param N Number of the variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ ///
+ OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo)
+ : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc,
+ LParenLoc, EndLoc, N),
+ ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPReductionClause(unsigned N)
+ : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N),
+ ColonLoc(), QualifierLoc(), NameInfo() {}
+
+ /// \brief Sets location of ':' symbol in clause.
+ void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+ /// \brief Sets the name info for specified reduction identifier.
+ void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+ /// \brief Sets the nested name specifier.
+ void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL The variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ ///
+ static OMPReductionClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo);
+ /// \brief Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ /// \brief Gets location of ':' symbol in clause.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ /// \brief Gets the name info for specified reduction identifier.
+ const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+ /// \brief Gets the nested name specifier.
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_reduction;
+ }
+};
+
+/// \brief This represents clause 'linear' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd linear(a,b : 2)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'linear'
+/// with variables 'a', 'b' and linear step '2'.
+///
+class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
+ friend class OMPClauseReader;
+ /// \brief Location of ':'.
+ SourceLocation ColonLoc;
+
+ /// \brief Sets the linear step for clause.
+ void setStep(Expr *Step) { *varlist_end() = Step; }
+
+ /// \brief Build 'linear' clause with given number of variables \a NumVars.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param NumVars Number of variables.
+ ///
+ OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ unsigned NumVars)
+ : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc,
+ EndLoc, NumVars),
+ ColonLoc(ColonLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param NumVars Number of variables.
+ ///
+ explicit OMPLinearClause(unsigned NumVars)
+ : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ NumVars),
+ ColonLoc(SourceLocation()) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL and a linear step
+ /// \a Step.
+ ///
+ /// \param C AST Context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ /// \param Step Linear step.
+ static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL, Expr *Step);
+
+ /// \brief Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param NumVars Number of variables.
+ ///
+ static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+ /// \brief Sets the location of ':'.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// \brief Returns the location of '('.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// \brief Returns linear step.
+ Expr *getStep() { return *varlist_end(); }
+ /// \brief Returns linear step.
+ const Expr *getStep() const { return *varlist_end(); }
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end() + 1));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_linear;
+ }
+};
+
+/// \brief This represents clause 'aligned' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp simd aligned(a,b : 8)
+/// \endcode
+/// In this example directive '#pragma omp simd' has clause 'aligned'
+/// with variables 'a', 'b' and alignment '8'.
+///
+class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+ friend class OMPClauseReader;
+ /// \brief Location of ':'.
+ SourceLocation ColonLoc;
+
+ /// \brief Sets the alignment for clause.
+ void setAlignment(Expr *A) { *varlist_end() = A; }
+
+ /// \brief Build 'aligned' clause with given number of variables \a NumVars.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param NumVars Number of variables.
+ ///
+ OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ unsigned NumVars)
+ : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc,
+ EndLoc, NumVars),
+ ColonLoc(ColonLoc) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param NumVars Number of variables.
+ ///
+ explicit OMPAlignedClause(unsigned NumVars)
+ : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ NumVars),
+ ColonLoc(SourceLocation()) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL and alignment \a A.
+ ///
+ /// \param C AST Context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ /// \param A Alignment.
+ static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation ColonLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ Expr *A);
+
+ /// \brief Creates an empty clause with the place for \a NumVars variables.
+ ///
+ /// \param C AST context.
+ /// \param NumVars Number of variables.
+ ///
+ static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);
+
+ /// \brief Sets the location of ':'.
+ void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }
+ /// \brief Returns the location of ':'.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+
+ /// \brief Returns alignment.
+ Expr *getAlignment() { return *varlist_end(); }
+ /// \brief Returns alignment.
+ const Expr *getAlignment() const { return *varlist_end(); }
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end() + 1));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_aligned;
+ }
+};
+
+/// \brief This represents clause 'copyin' in the '#pragma omp ...' directives.
+///
+/// \code
+/// #pragma omp parallel copyin(a,b)
+/// \endcode
+/// In this example directive '#pragma omp parallel' has clause 'copyin'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPCopyinClause(unsigned N)
+ : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPCopyinClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_copyin;
+ }
+};
+
+/// \brief This represents clause 'copyprivate' in the '#pragma omp ...'
+/// directives.
+///
+/// \code
+/// #pragma omp single copyprivate(a,b)
+/// \endcode
+/// In this example directive '#pragma omp single' has clause 'copyprivate'
+/// with the variables 'a' and 'b'.
+///
+class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc,
+ LParenLoc, EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPCopyprivateClause(unsigned N)
+ : OMPVarListClause<OMPCopyprivateClause>(
+ OMPC_copyprivate, SourceLocation(), SourceLocation(),
+ SourceLocation(), N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPCopyprivateClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_copyprivate;
+ }
+};
+
+/// \brief This represents pseudo clause 'flush' for the '#pragma omp flush'
+/// directive.
+///
+/// \code
+/// #pragma omp flush(a,b)
+/// \endcode
+/// In this example directive '#pragma omp flush' has pseudo clause 'flush'
+/// with the variables 'a' and 'b'.
+///
+class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+ /// \brief Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param N Number of the variables in the clause.
+ ///
+ OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc,
+ EndLoc, N) {}
+
+ /// \brief Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPFlushClause(unsigned N)
+ : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(),
+ SourceLocation(), SourceLocation(),
+ N) {}
+
+public:
+ /// \brief Creates clause with a list of variables \a VL.
+ ///
+ /// \param C AST context.
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL List of references to the variables.
+ ///
+ static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc,
+ ArrayRef<Expr *> VL);
+ /// \brief Creates an empty clause with \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ StmtRange children() {
+ return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_flush;
+ }
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h
index 5e41d955cfd7..aba88d6c5419 100644
--- a/include/clang/AST/OperationKinds.h
+++ b/include/clang/AST/OperationKinds.h
@@ -295,7 +295,10 @@ enum CastKind {
CK_BuiltinFnToFnPtr,
// Convert a zero value for OpenCL event_t initialization.
- CK_ZeroToOCLEvent
+ CK_ZeroToOCLEvent,
+
+ // Convert a pointer to a different address space.
+ CK_AddressSpaceConversion
};
static const CastKind CK_Invalid = static_cast<CastKind>(-1);
diff --git a/include/clang/AST/ParentMap.h b/include/clang/AST/ParentMap.h
index bd2ebf5dbedb..eece8510e9c4 100644
--- a/include/clang/AST/ParentMap.h
+++ b/include/clang/AST/ParentMap.h
@@ -53,7 +53,7 @@ public:
}
bool hasParent(Stmt* S) const {
- return getParent(S) != 0;
+ return getParent(S) != nullptr;
}
bool isConsumedExpr(Expr *E) const;
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 76426991cf47..349f4c44a4e0 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -41,7 +41,8 @@ struct PrintingPolicy {
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),
- MSWChar(LO.MicrosoftExt && !LO.WChar) { }
+ Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
+ IncludeNewlines(true) { }
/// \brief What language we're printing.
LangOptions LangOpts;
@@ -125,7 +126,7 @@ struct PrintingPolicy {
/// \brief When printing an anonymous tag name, also print the location of
/// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just
- /// prints "<anonymous>" for the name.
+ /// prints "(anonymous)" for the name.
bool AnonymousTagLocations : 1;
/// \brief When true, suppress printing of the __strong lifetime qualifier in
@@ -152,9 +153,16 @@ struct PrintingPolicy {
///
unsigned PolishForDeclaration : 1;
+ /// \brief When true, print the half-precision floating-point type as 'half'
+ /// instead of '__fp16'
+ unsigned Half : 1;
+
/// \brief When true, print the built-in wchar_t type as __wchar_t. For use in
/// Microsoft mode when wchar_t is not available.
unsigned MSWChar : 1;
+
+ /// \brief When true, include newlines after statements like "break", etc.
+ unsigned IncludeNewlines : 1;
};
} // end namespace clang
diff --git a/include/clang/AST/RawCommentList.h b/include/clang/AST/RawCommentList.h
index a4fcc108eb5d..8ba85c43f657 100644
--- a/include/clang/AST/RawCommentList.h
+++ b/include/clang/AST/RawCommentList.h
@@ -193,9 +193,7 @@ private:
SourceManager &SourceMgr;
std::vector<RawComment *> Comments;
- void addCommentsToFront(const std::vector<RawComment *> &C) {
- Comments.insert(Comments.begin(), C.begin(), C.end());
- }
+ void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
friend class ASTReader;
};
diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h
index 7268b3a8240c..4befb4506212 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -66,6 +66,10 @@ private:
// Alignment - Alignment of record in characters.
CharUnits Alignment;
+ /// RequiredAlignment - The required alignment of the object. In the MS-ABI
+ /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
+ CharUnits RequiredAlignment;
+
/// FieldOffsets - Array of field offsets in bits.
uint64_t *FieldOffsets;
@@ -78,9 +82,9 @@ private:
/// the size of the object without virtual bases.
CharUnits NonVirtualSize;
- /// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
+ /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
- CharUnits NonVirtualAlign;
+ CharUnits NonVirtualAlignment;
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
/// (either a base or a member). Will be zero if the class doesn't contain
@@ -100,10 +104,15 @@ private:
/// a primary base class.
bool HasExtendableVFPtr : 1;
- /// AlignAfterVBases - Force appropriate alignment after virtual bases are
- /// laid out in MS-C++-ABI.
- bool AlignAfterVBases : 1;
-
+ /// HasZeroSizedSubObject - True if this class contains a zero sized member
+ /// or base or a base with a zero sized member or base. Only used for
+ /// MS-ABI.
+ bool HasZeroSizedSubObject : 1;
+
+ /// \brief True if this class is zero sized or first base is zero sized or
+ /// has this property. Only used for MS-ABI.
+ bool LeadsWithZeroSizedBase : 1;
+
/// PrimaryBase - The primary base info for this record.
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
@@ -127,6 +136,7 @@ private:
friend class ASTContext;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
+ CharUnits requiredAlignment,
CharUnits datasize, const uint64_t *fieldoffsets,
unsigned fieldcount);
@@ -134,16 +144,18 @@ private:
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
+ CharUnits requiredAlignment,
bool hasOwnVFPtr, bool hasExtendableVFPtr,
CharUnits vbptroffset,
CharUnits datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
- CharUnits nonvirtualsize, CharUnits nonvirtualalign,
+ CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
const CXXRecordDecl *BaseSharingVBPtr,
- bool ForceAlign,
+ bool HasZeroSizedSubObject,
+ bool LeadsWithZeroSizedBase,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets);
@@ -187,10 +199,10 @@ public:
/// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
- CharUnits getNonVirtualAlign() const {
+ CharUnits getNonVirtualAlignment() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->NonVirtualAlign;
+ return CXXInfo->NonVirtualAlignment;
}
/// getPrimaryBase - Get the primary base for this record.
@@ -267,9 +279,17 @@ public:
return !CXXInfo->VBPtrOffset.isNegative();
}
- bool getAlignAfterVBases() const {
+ CharUnits getRequiredAlignment() const {
+ return RequiredAlignment;
+ }
+
+ bool hasZeroSizedSubObject() const {
+ return CXXInfo && CXXInfo->HasZeroSizedSubObject;
+ }
+
+ bool leadsWithZeroSizedBase() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->AlignAfterVBases;
+ return CXXInfo->LeadsWithZeroSizedBase;
}
/// getVBPtrOffset - Get the offset for virtual base table pointer.
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index d09550f0e2c2..ff46ffb94e70 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclFriend.h"
@@ -37,34 +38,24 @@
// using them is responsible for defining macro OPERATOR().
// All unary operators.
-#define UNARYOP_LIST() \
- OPERATOR(PostInc) OPERATOR(PostDec) \
- OPERATOR(PreInc) OPERATOR(PreDec) \
- OPERATOR(AddrOf) OPERATOR(Deref) \
- OPERATOR(Plus) OPERATOR(Minus) \
- OPERATOR(Not) OPERATOR(LNot) \
- OPERATOR(Real) OPERATOR(Imag) \
- OPERATOR(Extension)
+#define UNARYOP_LIST() \
+ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \
+ OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \
+ OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \
+ OPERATOR(Extension)
// All binary operators (excluding compound assign operators).
-#define BINOP_LIST() \
- OPERATOR(PtrMemD) OPERATOR(PtrMemI) \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) \
- OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) \
- OPERATOR(Shr) \
- \
- OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) \
- OPERATOR(GE) OPERATOR(EQ) OPERATOR(NE) \
- OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) \
- OPERATOR(LAnd) OPERATOR(LOr) \
- \
- OPERATOR(Assign) \
- OPERATOR(Comma)
+#define BINOP_LIST() \
+ OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \
+ OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \
+ OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \
+ OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \
+ OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
// All compound assign operators.
-#define CAO_LIST() \
- OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
- OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
+#define CAO_LIST() \
+ OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \
+ OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
namespace clang {
@@ -72,8 +63,11 @@ namespace clang {
// invokes CALL_EXPR, which must be a method call, on the derived
// object (s.t. a user of RecursiveASTVisitor can override the method
// in CALL_EXPR).
-#define TRY_TO(CALL_EXPR) \
- do { if (!getDerived().CALL_EXPR) return false; } while (0)
+#define TRY_TO(CALL_EXPR) \
+ do { \
+ if (!getDerived().CALL_EXPR) \
+ return false; \
+ } while (0)
/// \brief A class that does preorder depth-first traversal on the
/// entire Clang AST and visits each node.
@@ -136,11 +130,10 @@ namespace clang {
/// to return true, in which case all known implicit and explicit
/// instantiations will be visited at the same time as the pattern
/// from which they were produced.
-template<typename Derived>
-class RecursiveASTVisitor {
+template <typename Derived> class RecursiveASTVisitor {
public:
/// \brief Return a reference to the derived class.
- Derived &getDerived() { return *static_cast<Derived*>(this); }
+ Derived &getDerived() { return *static_cast<Derived *>(this); }
/// \brief Return whether this visitor should recurse into
/// template instantiations.
@@ -182,6 +175,13 @@ public:
/// otherwise (including when the argument is a Null type location).
bool TraverseTypeLoc(TypeLoc TL);
+ /// \brief Recursively visit an attribute, by dispatching to
+ /// Traverse*Attr() based on the argument's dynamic type.
+ ///
+ /// \returns false if the visitation was terminated early, true
+ /// otherwise (including when the argument is a Null type location).
+ bool TraverseAttr(Attr *At);
+
/// \brief Recursively visit a declaration, by dispatching to
/// Traverse*Decl() based on the argument's dynamic type.
///
@@ -244,7 +244,7 @@ public:
/// \brief Recursively visit a lambda capture.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaExpr::Capture *C);
+ bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
/// \brief Recursively visit the body of a lambda expression.
///
@@ -254,107 +254,114 @@ public:
/// \returns false if the visitation was terminated early, true otherwise.
bool TraverseLambdaBody(LambdaExpr *LE);
- // ---- Methods on Stmts ----
+ // ---- Methods on Attrs ----
+
+ // \brief Visit an attribute.
+ bool VisitAttr(Attr *A) { return true; }
- // Declare Traverse*() for all concrete Stmt classes.
+// Declare Traverse* and empty Visit* for all Attr classes.
+#define ATTR_VISITOR_DECLS_ONLY
+#include "clang/AST/AttrVisitor.inc"
+#undef ATTR_VISITOR_DECLS_ONLY
+
+// ---- Methods on Stmts ----
+
+// Declare Traverse*() for all concrete Stmt classes.
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- bool Traverse##CLASS(CLASS *S);
+#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
#include "clang/AST/StmtNodes.inc"
// The above header #undefs ABSTRACT_STMT and STMT upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
bool VisitStmt(Stmt *S) { return true; }
-#define STMT(CLASS, PARENT) \
- bool WalkUpFrom##CLASS(CLASS *S) { \
- TRY_TO(WalkUpFrom##PARENT(S)); \
- TRY_TO(Visit##CLASS(S)); \
- return true; \
- } \
+#define STMT(CLASS, PARENT) \
+ bool WalkUpFrom##CLASS(CLASS *S) { \
+ TRY_TO(WalkUpFrom##PARENT(S)); \
+ TRY_TO(Visit##CLASS(S)); \
+ return true; \
+ } \
bool Visit##CLASS(CLASS *S) { return true; }
#include "clang/AST/StmtNodes.inc"
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
- // operator methods. Unary operators are not classes in themselves
- // (they're all opcodes in UnaryOperator) but do have visitors.
-#define OPERATOR(NAME) \
- bool TraverseUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnary##NAME(S)); \
- TRY_TO(TraverseStmt(S->getSubExpr())); \
- return true; \
- } \
- bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
- TRY_TO(WalkUpFromUnaryOperator(S)); \
- TRY_TO(VisitUnary##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
+// operator methods. Unary operators are not classes in themselves
+// (they're all opcodes in UnaryOperator) but do have visitors.
+#define OPERATOR(NAME) \
+ bool TraverseUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnary##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getSubExpr())); \
+ return true; \
+ } \
+ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \
+ TRY_TO(WalkUpFromUnaryOperator(S)); \
+ TRY_TO(VisitUnary##NAME(S)); \
+ return true; \
+ } \
bool VisitUnary##NAME(UnaryOperator *S) { return true; }
UNARYOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
- // operator methods. Binary operators are not classes in themselves
- // (they're all opcodes in BinaryOperator) but do have visitors.
-#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
- bool TraverseBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFromBin##NAME(S)); \
- TRY_TO(TraverseStmt(S->getLHS())); \
- TRY_TO(TraverseStmt(S->getRHS())); \
- return true; \
- } \
- bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
- TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
- TRY_TO(VisitBin##NAME(S)); \
- return true; \
- } \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
+// operator methods. Binary operators are not classes in themselves
+// (they're all opcodes in BinaryOperator) but do have visitors.
+#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \
+ bool TraverseBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFromBin##NAME(S)); \
+ TRY_TO(TraverseStmt(S->getLHS())); \
+ TRY_TO(TraverseStmt(S->getRHS())); \
+ return true; \
+ } \
+ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \
+ TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \
+ TRY_TO(VisitBin##NAME(S)); \
+ return true; \
+ } \
bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
BINOP_LIST()
#undef OPERATOR
- // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
- // assignment methods. Compound assignment operators are not
- // classes in themselves (they're all opcodes in
- // CompoundAssignOperator) but do have visitors.
-#define OPERATOR(NAME) \
+// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
+// assignment methods. Compound assignment operators are not
+// classes in themselves (they're all opcodes in
+// CompoundAssignOperator) but do have visitors.
+#define OPERATOR(NAME) \
GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
CAO_LIST()
#undef OPERATOR
#undef GENERAL_BINOP_FALLBACK
- // ---- Methods on Types ----
- // FIXME: revamp to take TypeLoc's rather than Types.
+// ---- Methods on Types ----
+// FIXME: revamp to take TypeLoc's rather than Types.
- // Declare Traverse*() for all concrete Type classes.
+// Declare Traverse*() for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
#include "clang/AST/TypeNodes.def"
// The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Type classes.
bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
bool VisitType(Type *T) { return true; }
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
- TRY_TO(WalkUpFrom##BASE(T)); \
- TRY_TO(Visit##CLASS##Type(T)); \
- return true; \
- } \
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
+ TRY_TO(WalkUpFrom##BASE(T)); \
+ TRY_TO(Visit##CLASS##Type(T)); \
+ return true; \
+ } \
bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on TypeLocs ----
- // FIXME: this currently just calls the matching Type methods
+// ---- Methods on TypeLocs ----
+// FIXME: this currently just calls the matching Type methods
- // Declare Traverse*() for all concrete TypeLoc classes.
+// Declare Traverse*() for all concrete TypeLoc classes.
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
#include "clang/AST/TypeLocNodes.def"
// The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
@@ -373,34 +380,33 @@ public:
}
bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
- // Note that BASE includes trailing 'Type' which CLASS doesn't.
-#define TYPE(CLASS, BASE) \
- bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
- TRY_TO(Visit##CLASS##TypeLoc(TL)); \
- return true; \
- } \
+// Note that BASE includes trailing 'Type' which CLASS doesn't.
+#define TYPE(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
+ TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
+ TRY_TO(Visit##CLASS##TypeLoc(TL)); \
+ return true; \
+ } \
bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
#include "clang/AST/TypeNodes.def"
- // ---- Methods on Decls ----
+// ---- Methods on Decls ----
- // Declare Traverse*() for all concrete Decl classes.
+// Declare Traverse*() for all concrete Decl classes.
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- bool Traverse##CLASS##Decl(CLASS##Decl *D);
+#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
#include "clang/AST/DeclNodes.inc"
// The above header #undefs ABSTRACT_DECL and DECL upon exit.
// Define WalkUpFrom*() and empty Visit*() for all Decl classes.
bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
bool VisitDecl(Decl *D) { return true; }
-#define DECL(CLASS, BASE) \
- bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
- TRY_TO(WalkUpFrom##BASE(D)); \
- TRY_TO(Visit##CLASS##Decl(D)); \
- return true; \
- } \
+#define DECL(CLASS, BASE) \
+ bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
+ TRY_TO(WalkUpFrom##BASE(D)); \
+ TRY_TO(Visit##CLASS##Decl(D)); \
+ return true; \
+ } \
bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
#include "clang/AST/DeclNodes.inc"
@@ -422,13 +428,12 @@ private:
bool TraverseDeclContextHelper(DeclContext *DC);
bool TraverseFunctionHelper(FunctionDecl *D);
bool TraverseVarHelper(VarDecl *D);
+ bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
bool TraverseOMPClause(OMPClause *C);
-#define OPENMP_CLAUSE(Name, Class) \
- bool Visit##Class(Class *C);
+#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
#include "clang/Basic/OpenMPKinds.def"
/// \brief Process clauses with list of variables.
- template <typename T>
- void VisitOMPClauseList(T *Node);
+ template <typename T> bool VisitOMPClauseList(T *Node);
struct EnqueueJob {
Stmt *S;
@@ -440,7 +445,7 @@ private:
bool dataTraverseNode(Stmt *S, bool &EnqueueChildren);
};
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
SmallVector<EnqueueJob, 16> Queue;
@@ -457,7 +462,8 @@ bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
if (getDerived().shouldUseDataRecursionFor(CurrS)) {
if (job.StmtIt == Stmt::child_iterator()) {
bool EnqueueChildren = true;
- if (!dataTraverseNode(CurrS, EnqueueChildren)) return false;
+ if (!dataTraverseNode(CurrS, EnqueueChildren))
+ return false;
if (!EnqueueChildren) {
Queue.pop_back();
continue;
@@ -481,53 +487,57 @@ bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
bool &EnqueueChildren) {
- // Dispatch to the corresponding WalkUpFrom* function only if the derived
- // class didn't override Traverse* (and thus the traversal is trivial).
-#define DISPATCH_WALK(NAME, CLASS, VAR) \
- { \
- bool (Derived::*DerivedFn)(CLASS*) = &Derived::Traverse##NAME; \
- bool (Derived::*BaseFn)(CLASS*) = &RecursiveASTVisitor::Traverse##NAME; \
- if (DerivedFn == BaseFn) \
- return getDerived().WalkUpFrom##NAME(static_cast<CLASS*>(VAR)); \
- } \
- EnqueueChildren = false; \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR));
+// Dispatch to the corresponding WalkUpFrom* function only if the derived
+// class didn't override Traverse* (and thus the traversal is trivial).
+#define DISPATCH_WALK(NAME, CLASS, VAR) \
+ { \
+ bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME; \
+ bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME; \
+ if (DerivedFn == BaseFn) \
+ return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR)); \
+ } \
+ EnqueueChildren = false; \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR));
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
- BINOP_LIST()
+ BINOP_LIST()
#undef OPERATOR
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
- CAO_LIST()
+ CAO_LIST()
#undef OPERATOR
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
- UNARYOP_LIST()
+ UNARYOP_LIST()
#undef OPERATOR
}
}
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
+ case Stmt::NoStmtClass:
+ break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH_WALK(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_WALK(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
@@ -536,14 +546,16 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
return true;
}
-#define DISPATCH(NAME, CLASS, VAR) \
- return getDerived().Traverse##NAME(static_cast<CLASS*>(VAR))
+#define DISPATCH(NAME, CLASS, VAR) \
+ return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
if (!S)
return true;
+#define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR)
+
if (getDerived().shouldUseDataRecursionFor(S))
return dataTraverse(S);
@@ -552,27 +564,29 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
// below.
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
switch (BinOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case BO_##NAME: DISPATCH(Bin##NAME, BinaryOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME: \
+ DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
- BINOP_LIST()
+ BINOP_LIST()
#undef OPERATOR
#undef BINOP_LIST
-#define OPERATOR(NAME) \
- case BO_##NAME##Assign: \
- DISPATCH(Bin##NAME##Assign, CompoundAssignOperator, S);
+#define OPERATOR(NAME) \
+ case BO_##NAME##Assign: \
+ DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
- CAO_LIST()
+ CAO_LIST()
#undef OPERATOR
#undef CAO_LIST
}
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
switch (UnOp->getOpcode()) {
-#define OPERATOR(NAME) \
- case UO_##NAME: DISPATCH(Unary##NAME, UnaryOperator, S);
+#define OPERATOR(NAME) \
+ case UO_##NAME: \
+ DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
- UNARYOP_LIST()
+ UNARYOP_LIST()
#undef OPERATOR
#undef UNARYOP_LIST
}
@@ -580,41 +594,45 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
// Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
switch (S->getStmtClass()) {
- case Stmt::NoStmtClass: break;
+ case Stmt::NoStmtClass:
+ break;
#define ABSTRACT_STMT(STMT)
-#define STMT(CLASS, PARENT) \
- case Stmt::CLASS##Class: DISPATCH(CLASS, CLASS, S);
+#define STMT(CLASS, PARENT) \
+ case Stmt::CLASS##Class: \
+ DISPATCH_STMT(CLASS, CLASS, S);
#include "clang/AST/StmtNodes.inc"
}
return true;
}
-template<typename Derived>
+#undef DISPATCH_STMT
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
if (T.isNull())
return true;
switch (T->getTypeClass()) {
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) \
- case Type::CLASS: DISPATCH(CLASS##Type, CLASS##Type, \
- const_cast<Type*>(T.getTypePtr()));
+#define TYPE(CLASS, BASE) \
+ case Type::CLASS: \
+ DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
#include "clang/AST/TypeNodes.def"
}
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
if (TL.isNull())
return true;
switch (TL.getTypeLocClass()) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) \
- case TypeLoc::CLASS: \
+#define TYPELOC(CLASS, BASE) \
+ case TypeLoc::CLASS: \
return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
#include "clang/AST/TypeLocNodes.def"
}
@@ -622,8 +640,12 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
return true;
}
+// Define the Traverse*Attr(Attr* A) methods
+#define VISITORCLASS RecursiveASTVisitor
+#include "clang/AST/AttrVisitor.inc"
+#undef VISITORCLASS
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
if (!D)
return true;
@@ -635,19 +657,27 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
switch (D->getKind()) {
#define ABSTRACT_DECL(DECL)
-#define DECL(CLASS, BASE) \
- case Decl::CLASS: DISPATCH(CLASS##Decl, CLASS##Decl, D);
+#define DECL(CLASS, BASE) \
+ case Decl::CLASS: \
+ if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
+ return false; \
+ break;
#include "clang/AST/DeclNodes.inc"
- }
+ }
+ // Visit any attributes attached to this declaration.
+ for (auto *I : D->attrs()) {
+ if (!getDerived().TraverseAttr(I))
+ return false;
+ }
return true;
}
#undef DISPATCH
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
+ NestedNameSpecifier *NNS) {
if (!NNS)
return true;
@@ -669,14 +699,14 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
- NestedNameSpecifierLoc NNS) {
+ NestedNameSpecifierLoc NNS) {
if (!NNS)
return true;
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
+ if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
+ TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
@@ -694,9 +724,9 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
- DeclarationNameInfo NameInfo) {
+ DeclarationNameInfo NameInfo) {
switch (NameInfo.getName().getNameKind()) {
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
@@ -719,7 +749,7 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
@@ -729,9 +759,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
- const TemplateArgument &Arg) {
+ const TemplateArgument &Arg) {
switch (Arg.getKind()) {
case TemplateArgument::Null:
case TemplateArgument::Declaration:
@@ -745,7 +775,7 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(Arg.getAsExpr());
@@ -760,9 +790,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
// FIXME: no template name location?
// FIXME: no source locations for a template argument pack?
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
- const TemplateArgumentLoc &ArgLoc) {
+ const TemplateArgumentLoc &ArgLoc) {
const TemplateArgument &Arg = ArgLoc.getArgument();
switch (Arg.getKind()) {
@@ -784,9 +814,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
case TemplateArgument::TemplateExpansion:
if (ArgLoc.getTemplateQualifierLoc())
TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
- ArgLoc.getTemplateQualifierLoc()));
+ ArgLoc.getTemplateQualifierLoc()));
return getDerived().TraverseTemplateName(
- Arg.getAsTemplateOrTemplatePattern());
+ Arg.getAsTemplateOrTemplatePattern());
case TemplateArgument::Expression:
return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
@@ -799,10 +829,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
- const TemplateArgument *Args,
- unsigned NumArgs) {
+ const TemplateArgument *Args, unsigned NumArgs) {
for (unsigned I = 0; I != NumArgs; ++I) {
TRY_TO(TraverseTemplateArgument(Args[I]));
}
@@ -810,9 +839,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
- CXXCtorInitializer *Init) {
+ CXXCtorInitializer *Init) {
if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
@@ -821,197 +850,164 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
return true;
}
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseLambdaCapture(
- LambdaExpr *LE, const LambdaExpr::Capture *C) {
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
+ const LambdaCapture *C) {
if (C->isInitCapture())
TRY_TO(TraverseDecl(C->getCapturedVar()));
return true;
}
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
TRY_TO(TraverseStmt(LE->getBody()));
return true;
}
-
// ----------------- Type traversal -----------------
// This macro makes available a variable T, the passed-in type.
-#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE (TYPE *T) { \
- TRY_TO(WalkUpFrom##TYPE (T)); \
- { CODE; } \
- return true; \
+#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
+ TRY_TO(WalkUpFrom##TYPE(T)); \
+ { CODE; } \
+ return true; \
}
-DEF_TRAVERSE_TYPE(BuiltinType, { })
+DEF_TRAVERSE_TYPE(BuiltinType, {})
-DEF_TRAVERSE_TYPE(ComplexType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(PointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(BlockPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(BlockPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(LValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(LValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(RValueReferenceType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(RValueReferenceType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseType(QualType(T->getClass(), 0)));
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+ TRY_TO(TraverseType(QualType(T->getClass(), 0)));
+ TRY_TO(TraverseType(T->getPointeeType()));
+})
-DEF_TRAVERSE_TYPE(DecayedType, {
- TRY_TO(TraverseType(T->getOriginalType()));
- })
+DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(ConstantArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
-DEF_TRAVERSE_TYPE(IncompleteArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ConstantArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
+
+DEF_TRAVERSE_TYPE(IncompleteArrayType,
+ { TRY_TO(TraverseType(T->getElementType())); })
DEF_TRAVERSE_TYPE(VariableArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
- TRY_TO(TraverseType(T->getElementType()));
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- })
+ TRY_TO(TraverseType(T->getElementType()));
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+})
DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
- if (T->getSizeExpr())
- TRY_TO(TraverseStmt(T->getSizeExpr()));
- TRY_TO(TraverseType(T->getElementType()));
- })
+ if (T->getSizeExpr())
+ TRY_TO(TraverseStmt(T->getSizeExpr()));
+ TRY_TO(TraverseType(T->getElementType()));
+})
-DEF_TRAVERSE_TYPE(VectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(ExtVectorType, {
- TRY_TO(TraverseType(T->getElementType()));
- })
+DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
-DEF_TRAVERSE_TYPE(FunctionNoProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
- })
+DEF_TRAVERSE_TYPE(FunctionNoProtoType,
+ { TRY_TO(TraverseType(T->getReturnType())); })
DEF_TRAVERSE_TYPE(FunctionProtoType, {
- TRY_TO(TraverseType(T->getResultType()));
+ TRY_TO(TraverseType(T->getReturnType()));
- for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
- AEnd = T->arg_type_end();
- A != AEnd; ++A) {
- TRY_TO(TraverseType(*A));
- }
+ for (const auto &A : T->param_types()) {
+ TRY_TO(TraverseType(A));
+ }
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
- }
- })
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPE(TypedefType, { })
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPE(TypedefType, {})
-DEF_TRAVERSE_TYPE(TypeOfExprType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(TypeOfExprType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
-DEF_TRAVERSE_TYPE(TypeOfType, {
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
-DEF_TRAVERSE_TYPE(DecltypeType, {
- TRY_TO(TraverseStmt(T->getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPE(DecltypeType,
+ { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
DEF_TRAVERSE_TYPE(UnaryTransformType, {
- TRY_TO(TraverseType(T->getBaseType()));
- TRY_TO(TraverseType(T->getUnderlyingType()));
- })
+ TRY_TO(TraverseType(T->getBaseType()));
+ TRY_TO(TraverseType(T->getUnderlyingType()));
+})
-DEF_TRAVERSE_TYPE(AutoType, {
- TRY_TO(TraverseType(T->getDeducedType()));
- })
+DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
-DEF_TRAVERSE_TYPE(RecordType, { })
-DEF_TRAVERSE_TYPE(EnumType, { })
-DEF_TRAVERSE_TYPE(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPE(RecordType, {})
+DEF_TRAVERSE_TYPE(EnumType, {})
+DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPE(AttributedType, {
- TRY_TO(TraverseType(T->getModifiedType()));
- })
+DEF_TRAVERSE_TYPE(AttributedType,
+ { TRY_TO(TraverseType(T->getModifiedType())); })
-DEF_TRAVERSE_TYPE(ParenType, {
- TRY_TO(TraverseType(T->getInnerType()));
- })
+DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
- })
-
-DEF_TRAVERSE_TYPE(DependentNameType, {
+ if (T->getQualifier()) {
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- })
+ }
+ TRY_TO(TraverseType(T->getNamedType()));
+})
+
+DEF_TRAVERSE_TYPE(DependentNameType,
+ { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
- })
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+ TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+})
-DEF_TRAVERSE_TYPE(PackExpansionType, {
- TRY_TO(TraverseType(T->getPattern()));
- })
+DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
-DEF_TRAVERSE_TYPE(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPE(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (T->getBaseType().getTypePtr() != T)
- TRY_TO(TraverseType(T->getBaseType()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (T->getBaseType().getTypePtr() != T)
+ TRY_TO(TraverseType(T->getBaseType()));
+})
-DEF_TRAVERSE_TYPE(ObjCObjectPointerType, {
- TRY_TO(TraverseType(T->getPointeeType()));
- })
+DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
+ { TRY_TO(TraverseType(T->getPointeeType())); })
-DEF_TRAVERSE_TYPE(AtomicType, {
- TRY_TO(TraverseType(T->getValueType()));
- })
+DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
#undef DEF_TRAVERSE_TYPE
@@ -1022,19 +1018,19 @@ DEF_TRAVERSE_TYPE(AtomicType, {
// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
// continue to work.
-#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
- template<typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
- if (getDerived().shouldWalkTypesOfTypeLocs()) \
- TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE*>(TL.getTypePtr()))); \
- TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
- { CODE; } \
- return true; \
- }
-
-template<typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
- QualifiedTypeLoc TL) {
+#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
+ template <typename Derived> \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ if (getDerived().shouldWalkTypesOfTypeLocs()) \
+ TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
+ TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
+ { CODE; } \
+ return true; \
+ }
+
+template <typename Derived>
+bool
+RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
// Move this over to the 'main' typeloc tree. Note that this is a
// move -- we pretend that we were really looking at the unqualified
// typeloc all along -- rather than a recursion, so we don't follow
@@ -1053,42 +1049,40 @@ bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
return TraverseTypeLoc(TL.getUnqualifiedLoc());
}
-DEF_TRAVERSE_TYPELOC(BuiltinType, { })
+DEF_TRAVERSE_TYPELOC(BuiltinType, {})
// FIXME: ComplexTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ComplexType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(PointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(BlockPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(BlockPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(LValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(LValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(RValueReferenceType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(RValueReferenceType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
// FIXME: location of base class?
// We traverse this in the type case as well, but how is it not reached through
// the pointee type?
DEF_TRAVERSE_TYPELOC(MemberPointerType, {
- TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+ TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
+ TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
+})
-DEF_TRAVERSE_TYPELOC(DecayedType, {
- TRY_TO(TraverseTypeLoc(TL.getOriginalLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AdjustedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
+
+DEF_TRAVERSE_TYPELOC(DecayedType,
+ { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
// This isn't available for ArrayType, but is for the ArrayTypeLoc.
TRY_TO(TraverseStmt(TL.getSizeExpr()));
@@ -1096,158 +1090,147 @@ bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
}
DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(VariableArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
- TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
- return TraverseArrayTypeLocHelper(TL);
- })
+ TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
+ return TraverseArrayTypeLocHelper(TL);
+})
// FIXME: order? why not size expr first?
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
- if (TL.getTypePtr()->getSizeExpr())
- TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ if (TL.getTypePtr()->getSizeExpr())
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(VectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
// FIXME: size and attributes
// FIXME: base VectorTypeLoc is unfinished
DEF_TRAVERSE_TYPELOC(ExtVectorType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
+})
-DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
- })
+DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
+ { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
// FIXME: location of exception specifications (attributes?)
DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
- TRY_TO(TraverseTypeLoc(TL.getResultLoc()));
+ TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
- const FunctionProtoType *T = TL.getTypePtr();
+ const FunctionProtoType *T = TL.getTypePtr();
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- if (TL.getArg(I)) {
- TRY_TO(TraverseDecl(TL.getArg(I)));
- } else if (I < T->getNumArgs()) {
- TRY_TO(TraverseType(T->getArgType(I)));
- }
+ for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
+ if (TL.getParam(I)) {
+ TRY_TO(TraverseDecl(TL.getParam(I)));
+ } else if (I < T->getNumParams()) {
+ TRY_TO(TraverseType(T->getParamType(I)));
}
+ }
- for (FunctionProtoType::exception_iterator E = T->exception_begin(),
- EEnd = T->exception_end();
- E != EEnd; ++E) {
- TRY_TO(TraverseType(*E));
- }
- })
+ for (const auto &E : T->exceptions()) {
+ TRY_TO(TraverseType(E));
+ }
+})
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, { })
-DEF_TRAVERSE_TYPELOC(TypedefType, { })
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
+DEF_TRAVERSE_TYPELOC(TypedefType, {})
-DEF_TRAVERSE_TYPELOC(TypeOfExprType, {
- TRY_TO(TraverseStmt(TL.getUnderlyingExpr()));
- })
+DEF_TRAVERSE_TYPELOC(TypeOfExprType,
+ { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
DEF_TRAVERSE_TYPELOC(TypeOfType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
// FIXME: location of underlying expr
DEF_TRAVERSE_TYPELOC(DecltypeType, {
- TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
- })
+ TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
+})
DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
- TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
- })
+ TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(AutoType, {
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
- })
+ TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+})
-DEF_TRAVERSE_TYPELOC(RecordType, { })
-DEF_TRAVERSE_TYPELOC(EnumType, { })
-DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, { })
-DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, { })
+DEF_TRAVERSE_TYPELOC(RecordType, {})
+DEF_TRAVERSE_TYPELOC(EnumType, {})
+DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
+DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
// FIXME: use the loc for the template name?
DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, { })
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-DEF_TRAVERSE_TYPELOC(ParenType, {
- TRY_TO(TraverseTypeLoc(TL.getInnerLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
-DEF_TRAVERSE_TYPELOC(AttributedType, {
- TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AttributedType,
+ { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
- })
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
+ TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- })
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
+ if (TL.getQualifierLoc()) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ }
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
- })
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+ }
+})
-DEF_TRAVERSE_TYPELOC(PackExpansionType, {
- TRY_TO(TraverseTypeLoc(TL.getPatternLoc()));
- })
+DEF_TRAVERSE_TYPELOC(PackExpansionType,
+ { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
-DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, { })
+DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
- // We have to watch out here because an ObjCInterfaceType's base
- // type is itself.
- if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
- TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
- })
+ // We have to watch out here because an ObjCInterfaceType's base
+ // type is itself.
+ if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
+ TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
+})
-DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, {
- TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
- })
+DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
+ { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
-DEF_TRAVERSE_TYPELOC(AtomicType, {
- TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
- })
+DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
#undef DEF_TRAVERSE_TYPELOC
@@ -1258,195 +1241,191 @@ DEF_TRAVERSE_TYPELOC(AtomicType, {
// Therefore each Traverse* only needs to worry about children other
// than those.
-template<typename Derived>
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
if (!DC)
return true;
- for (DeclContext::decl_iterator Child = DC->decls_begin(),
- ChildEnd = DC->decls_end();
- Child != ChildEnd; ++Child) {
+ for (auto *Child : DC->decls()) {
// BlockDecls and CapturedDecls are traversed through BlockExprs and
// CapturedStmts respectively.
- if (!isa<BlockDecl>(*Child) && !isa<CapturedDecl>(*Child))
- TRY_TO(TraverseDecl(*Child));
+ if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
+ TRY_TO(TraverseDecl(Child));
}
return true;
}
// This macro makes available a variable D, the passed-in decl.
-#define DEF_TRAVERSE_DECL(DECL, CODE) \
-template<typename Derived> \
-bool RecursiveASTVisitor<Derived>::Traverse##DECL (DECL *D) { \